这是一个关于使用python从不同形式的相同数据创建类或类型的实例的最佳实践的问题.使用类方法是否更好,或者更好地完全使用单独的函数?假设我有一个用于描述文档大小的类.(注意:这只是一个例子.我想知道创建类实例的最佳方法,而不是描述文档大小的最佳方法.)
class Size(object):
"""
Utility object used to describe the size of a document.
"""
BYTE = 8
KILO = 1024
def __init__(self, bits):
self._bits = bits
@property
def bits(self):
return float(self._bits)
@property
def bytes(self):
return self.bits / self.BYTE
@property
def kilobits(self):
return self.bits / self.KILO
@property
def kilobytes(self):
return self.bytes / self.KILO
@property
def megabits(self):
return self.kilobits / self.KILO
@property
def megabytes(self):
return self.kilobytes / self.KILO
Run Code Online (Sandbox Code Playgroud)
我的__init__方法采用以位表示的大小值(位和唯一的位,我想保持这种方式),但是假设我有一个以字节为单位的大小值,我想创建一个类的实例.使用类方法是否更好,或者更好地完全使用单独的函数?
class Size(object):
"""
Utility object used to describe …Run Code Online (Sandbox Code Playgroud) 我正在使用该subprocess模块从python启动进程.我希望能够在写入/缓冲后立即访问输出(stdout,stderr).
例如,假设我想运行一个名为counter.pyvia a 的python文件subprocess.内容counter.py如下:
import sys
for index in range(10):
# Write data to standard out.
sys.stdout.write(str(index))
# Push buffered data to disk.
sys.stdout.flush()
Run Code Online (Sandbox Code Playgroud)
负责执行该counter.py示例的父进程如下:
import subprocess
command = ['python', 'counter.py']
process = subprocess.Popen(
cmd,
bufsize=1,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
Run Code Online (Sandbox Code Playgroud)
使用该counter.py示例,我可以在流程完成之前访问数据.这很棒!这正是我想要的.但是,删除该sys.stdout.flush()调用会阻止在我想要的时间访问数据.这是不好的!这正是我不想要的.我的理解是flush()调用强制将数据写入磁盘,在将数据写入磁盘之前,它只存在于缓冲区中.请记住,我希望能够运行任何进程.我不希望这个过程执行这种刷新,但我仍然期望数据可以实时(或接近它).有没有办法实现这个目标?
关于父进程的快速说明.您可能会注意到我正在使用bufsize=0线路缓冲.我希望这会导致每行的磁盘刷新,但它似乎不会那样工作.这个论点如何运作?
您还会注意到我正在使用subprocess.PIPE.这是因为它似乎是在父进程和子进程之间生成IO对象的唯一值.我通过查看模块中的Popen._get_handles方法得出了这个结论subprocess(我在这里指的是Windows定义).有两个重要的变量,c2pread而c2pwrite …
何时以及如何在python中使用静态方法?我们已经建立了使用类方法作为工厂方法来创建对象的实例应该尽可能避免.换句话说,使用类方法作为替代构造函数并不是最佳实践(请参阅python对象的Factory方法 - 最佳实践).
假设我有一个用于表示数据库中某些实体数据的类.想象一下,数据是一个dict包含字段名称和字段值的对象,其中一个字段是使数据唯一的ID号.
class Entity(object):
def __init__(self, data, db_connection):
self._data = data
self._db_connection
Run Code Online (Sandbox Code Playgroud)
这里我的__init__方法采用实体数据dict对象.假设我只有一个ID号,我想创建一个Entity实例.首先,我需要找到其余的数据,然后创建我的Entity对象的实例.从我之前的问题中,我们确定应尽可能避免使用类方法作为工厂方法.
class Entity(object):
@classmethod
def from_id(cls, id_number, db_connection):
filters = [['id', 'is', id_number]]
data = db_connection.find(filters)
return cls(data, db_connection)
def __init__(self, data, db_connection):
self._data = data
self._db_connection
# Create entity
entity = Entity.from_id(id_number, db_connection)
Run Code Online (Sandbox Code Playgroud)
上面是一个例子,说明如果有替代方案,不做或至少不做什么.现在我想知道是否编辑我的类方法,以便它更像是一个实用工具方法,而更少的工厂方法是一个有效的解决方案.换句话说,以下示例是否符合使用静态方法的最佳实践.
class Entity(object):
@staticmethod
def data_from_id(id_number, db_connection):
filters = [['id', 'is', id_number]]
data = db_connection.find(filters)
return data
# Create entity …Run Code Online (Sandbox Code Playgroud) 我正在使用python的subprocess模块来启动一个新进程.我想实时捕获新进程的输出,以便我可以用它做事(显示它,解析它等).我已经看到很多关于如何做到这一点的例子,一些使用自定义文件类对象,一些使用threading,一些尝试读取输出直到进程完成.
stdin,stdout和stderr.stdout和stderr值.读取输出示例(见下文)
对我来说最有意义的例子是阅读stdout,stderr直到过程结束.这是一些示例代码:
import subprocess
# Start a process which prints the options to the python program.
process = subprocess.Popen(
["python", "-h"],
bufsize=1,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
# While the process is running, display the output to the user.
while True:
# Read standard output data.
for stdout_line in iter(process.stdout.readline, ""):
# Display standard output data.
sys.stdout.write(stdout_line)
# …Run Code Online (Sandbox Code Playgroud) 我在这里做了一些非Pythonic的事情吗?或者这是一个 pylint bug?
class Thing(object):
"""
Thing used for stackoverflow example.
"""
def __init__(self, something):
"""
Initialize Thing.
"""
# Set defaults.
self._something = None
# Set values using getter/setter methods - this allows for checks.
self.something = something
@property
def something(self):
"""
Get something
"""
return self._something
@something.setter
def something(self, value):
"""
Set something.
"""
# Some value checking here.
self._something = value
Run Code Online (Sandbox Code Playgroud)
我的印象是使用属性装饰器是实现属性的合理方式。皮林特则不然。Pylint 给我以下错误:
Thing: Too many instance attributes (2/1)
Thing.something: An attribute affected in thing line 10 …Run Code Online (Sandbox Code Playgroud) python ×5
coding-style ×2
subprocess ×2
buffer ×1
class-method ×1
decorator ×1
flush ×1
pipe ×1
properties ×1
pylint ×1
stdout ×1