Python:声明构造函数的灵活方式

Python:声明构造函数的灵活方式,python,constructor,Python,Constructor,为一个类声明多个构造函数的干净方法是什么 例如,假设我有一个项类。创建项目的一种方法(例如 做同样事情的另一种方法可能是 item = Item(otherItem) 还有另一种方法。。也许在某些情况下,我没有价格,所以我只想通过 item = Item(product_id, name,description) 还有一种情况可能是 item = Item(product_id,price) 我的另一个问题是: 有些私有变量可能在运行时初始化。 假设我有一些随机变量itemCount,我

为一个类声明多个构造函数的干净方法是什么

例如,假设我有一个
类。创建项目的一种方法(例如

做同样事情的另一种方法可能是

item = Item(otherItem)
还有另一种方法。。也许在某些情况下,我没有价格,所以我只想通过

item = Item(product_id, name,description)
还有一种情况可能是

item = Item(product_id,price)

我的另一个问题是: 有些私有变量可能在运行时初始化。 假设我有一些随机变量
itemCount
,我想在内部跟踪它

我如何声明我不必将其置于初始化模式,而是在运行时的某个地方。。 我可以做类似的事情

self._count +=1

谢谢

提供多个构造函数的两种最常见的方法是:

  • 下面是一个演示如何使用classmethod将fromkeys()实现为替代类构造函数的示例:

    @classmethod
    def fromkeys(cls, iterable, value=None):
        '''OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S.
        If not specified, the value defaults to None.
    
        '''
        self = cls()
        for key in iterable:
            self[key] = value
        return self
    
    作为另一种常用方法的示例,标准库中有:

    class SymbolTableFactory:
        def __init__(self):
            self.__memo = weakref.WeakValueDictionary()
    
        def new(self, table, filename):
            if table.type == _symtable.TYPE_FUNCTION:
                return Function(table, filename)
            if table.type == _symtable.TYPE_CLASS:
                return Class(table, filename)
            return SymbolTable(table, filename)
    

    您可以使用默认参数:

    class Item(object):
    
      def __init__(self, product_id = None, name = None, description = None, price = None)
          ... implementation ...
    
    def __init__(self, product_id, name=None, description=None, price=None):
        ...
    
    如果默认值应该有所不同,则可以替换
    None
    的任何值

    用法示例:

    item1 = Item(product_id = 4, price = 13) # use the field name!
    item2 = Item(name = "hammer", description = "used to belong to Thor")
    

    对于复制构造函数,
    item=item(otherItem)
    ,@Raymond对类方法和工厂函数的建议可能是最具python风格的方式



    更新:关于Python中的多个构造函数的问题。它还提到使用
    *args
    **kwargs

    复制通常是通过实例上的
    copy()
    方法完成的,而不是通过提供“复制构造函数”,因此

    而不是

    item = Item(other_item)
    
    您提到的所有其他构造函数签名都可以通过默认参数和关键字参数轻松处理:

    class Item(object):
    
      def __init__(self, product_id = None, name = None, description = None, price = None)
          ... implementation ...
    
    def __init__(self, product_id, name=None, description=None, price=None):
        ...
    

    如果您想要另一个具有完全不同代码的构造函数,那么使用
    classmethod
    是正确的方法——请参见Raymond Hettinger的答案。

    Hi。。但是在这个方法中。。让我们在初始化中说我不想要名字。。但是要传递的描述。。那么这是如何做到的..就像项目(123,描述)。。是名字还是描述??wil it figure outGuido强烈反对以这种方式使用可选/命名参数。例如,这就是为什么我们既有itertools.ifilter()又有itertools.ifilterfalse(),而不是一个带有切换行为标志的工具。同样,datetime类使用多个单独的构造函数(现在是from_ordinal、from_timestamp)。如果您要向其他Python程序员提供建议,它应该与Python的工作方式相匹配。如果可以创建无价之宝,那么为price设置一个默认参数是合理的,但是克隆的otheritem情况需要一个classmethod。虽然可以这样做,但可选/命名参数似乎是完成相同任务的更具python风格的方法。实际上,我很少选择多个构造函数而不是可选参数。