Python:灵活声明构造函数的方法
如何干净利落地为一个类声明多个构造函数?
比如说,我有一个叫做 Item
的类。创建一个 Item 的一种方法是:
item = Item(product_id, name, description,price)
另一种做法可能是:
item = Item(otherItem)
还有一种情况是.. 也许在某些情况下我没有价格,所以我只想传递:
item = Item(product_id, name,description)
再比如另一种情况可能是:
item = Item(product_id,price)
我还有一个问题:
有一些私有变量可能在运行时被初始化。
假设我有一个随机变量 itemCount
,我想在内部跟踪它。
我该如何声明它,这样我就不需要在初始化时设置,而是在运行时的某个地方.. 我可以这样做:
self._count +=1
谢谢
3 个回答
1
通常,复制操作是通过实例上的一个 copy()
方法来完成的,而不是通过提供一个“复制构造函数”。所以,
item = other_item.copy()
而不是
item = Item(other_item)
你提到的其他构造函数的写法,可以很简单地通过默认参数和关键字参数来处理:
def __init__(self, product_id, name=None, description=None, price=None):
...
如果你想要一个有完全不同代码的构造函数,那么使用 classmethod
是正确的做法——可以参考Raymond Hettinger的回答。
4
提供多个构造函数的两种最常见的方法是:
这里有一个来自标准库的例子,展示了collections.OrderedDict是如何使用类方法来实现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
作为另一种常见方法的例子,这里有一个在标准库中使用的工厂函数,它出现在symtable.py中:
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)
1
你可以使用默认参数:
class Item(object):
def __init__(self, product_id = None, name = None, description = None, price = None)
... implementation ...
如果你希望默认值是其他的东西,可以把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
。