小编Yan*_*ani的帖子

物体的工厂方法 - 最佳实践?

这是一个关于使用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)

python coding-style decorator factory-method class-method

23
推荐指数
1
解决办法
2万
查看次数

使用python从子进程读取输出

上下文

我正在使用该subprocess模块从python启动进程.我希望能够在写入/缓冲后立即访问输出(stdout,stderr).

  • 该解决方案必须支持Windows 7.我也需要Unix系统的解决方案,但我怀疑Windows案例更难以解决.
  • 该解决方案应该支持Python 2.6.我目前仅限于Python 2.6,但仍然赞赏使用更高版本的Python的解决方案.
  • 解决方案不应使用第三方库.理想情况下,我会喜欢使用标准库的解决方案,但我愿意接受建议.
  • 解决方案必须适用于任何流程.假设无法控制正在执行的进程.

儿童过程

例如,假设我想运行一个名为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定义).有两个重要的变量,c2preadc2pwrite …

python buffer subprocess pipe flush

14
推荐指数
1
解决办法
2621
查看次数

在python中使用静态方法 - 最佳实践

何时以及如何在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 static-methods coding-style

13
推荐指数
3
解决办法
2万
查看次数

使用python捕获进程输出的最佳方法是什么?

我正在使用python的subprocess模块来启动一个新进程.我想实时捕获新进程的输出,以便我可以用它做事(显示它,解析它等).我已经看到很多关于如何做到这一点的例子,一些使用自定义文件类对象,一些使用threading,一些尝试读取输出直到进程完成.

文件对象示例(单击我)

  • 我宁愿不使用自定义类文件的对象,因为我想允许用户为提供自己的价值观stdin,stdoutstderr.

线程示例(点击我)

  • 我真的不明白为什么需要线程,所以我不愿意遵循这个例子.如果有人可以解释为什么线程示例有意义我会很高兴听.但是,此示例还限制用户提供自己的值stdoutstderr值.

读取输出示例(见下文)

对我来说最有意义的例子是阅读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)

python subprocess stdout

5
推荐指数
1
解决办法
1025
查看次数

Python - 属性和 Pylint

我在这里做了一些非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 properties pylint python-decorators

5
推荐指数
0
解决办法
847
查看次数