为对象的工厂方法 - 最佳做法?(Factory method for objects - best

2019-07-20 06:25发布

这是关于创建从不同的形式使用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

__init__方法需要在位代表的大小值(位只有位,我想继续保持这种方式),但可以说,我有个字节的大小值,我想我的创建类的实例。 是更好地使用类方法还是更干脆使用一个单独的功能?

class Size(object):
    """
    Utility object used to describe the size of a document.
    """

    BYTE = 8
    KILO = 1024

    @classmethod
    def from_bytes(cls, bytes):
        bits = bytes * cls.BYTE
        return cls(bits)

要么

def create_instance_from_bytes(bytes):
    bits = bytes * Size.BYTE
    return Size(bits)

这可能似乎不是一个问题,也许这两个例子都是有效的,但每次我需要实现这样的时间去想它。 在很长一段时间,我宁愿类方法的方法,因为我喜欢搭售类和工厂方法在一起的组织效益。 此外,使用一个类的方法保留到创建任意子类的实例所以它更加面向对象的能力。 在另一方面,一个朋友曾经说:“如果有疑问,执行标准库做什么”,我还没有找到标准库的一个例子。

Answer 1:

首先,大多数的时候,你认为你需要这样的事情,你不这样做; 它是你试图把Python的Java等标志,而解决的办法就是退一步问,为什么你需要一个工厂。

通常情况下,以最简单的做法是只与违约/可选/关键字参数的构造函数。 即使案件你永远不会用Java编写,甚至案件的方式,其中重载的构造函数会觉得错在C ++或ObjC,可能看起来非常自然的Python编写的。 例如, size = Size(bytes=20)size = Size(20, Size.BYTES)看起来合理的。 对于这个问题,一个Bytes(20)从继承类Size ,并增加了绝对只是一个__init__超载看起来是合理的。 这些都是微不足道的定义:

def __init__(self, *, bits=None, bytes=None, kilobits=None, kilobytes=None):

要么:

BITS, BYTES, KILOBITS, KILOBYTES = 1, 8, 1024, 8192 # or object(), object(), object(), object()
def __init__(self, count, unit=Size.BITS):

但是,有时候需要工厂函数。 所以,你会怎么做呢? 那么,有两种东西,往往是集中到“工厂”。

@classmethod是做一个“交替构造函数” -there是示例遍布stdlib-惯用方式itertools.chain.from_iterabledatetime.datetime.fromordinal

功能是做一个“我不在乎实际的类是什么”工厂惯用的方式。 看,例如,内置的open功能。 你知道它返回3.3? 你关心? 不。 这就是为什么它是一个函数,而不是io.TextIOWrapper.open或什么的。

你给出的例子似乎是一个完全合法的使用情况,以及漂亮显然属于“备用构造的” bin(如果它不适合进入“构造与额外的参数的” bin)。



文章来源: Factory method for objects - best practice?