且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何根据参数类型重载__init__方法?

更新时间:2023-11-26 18:08:34

获取替代构造函数"的更整洁的方法是使用类方法.例如:

A much neater way to get 'alternate constructors' is to use classmethods. For instance:

>>> class MyData:
...     def __init__(self, data):
...         "Initialize MyData from a sequence"
...         self.data = data
...     
...     @classmethod
...     def fromfilename(cls, filename):
...         "Initialize MyData from a file"
...         data = open(filename).readlines()
...         return cls(data)
...     
...     @classmethod
...     def fromdict(cls, datadict):
...         "Initialize MyData from a dict's items"
...         return cls(datadict.items())
... 
>>> MyData([1, 2, 3]).data
[1, 2, 3]
>>> MyData.fromfilename("/tmp/foobar").data
['foo\n', 'bar\n', 'baz\n']
>>> MyData.fromdict({"spam": "ham"}).data
[('spam', 'ham')]

之所以整洁,是因为毫无疑问期望使用哪种类型,并且您不必强迫猜测调用者打算如何使用它给您的数据类型. isinstance(x, basestring)的问题在于,调用者无法告诉您,例如,即使类型不是基本字符串,您也应将其视为字符串(而不是其他序列).也许调用者希望将同一类型用于不同目的,有时作为单个项目使用,有时作为一系列项目使用.明确的表达消除了所有疑问,并导致了更健壮和更清晰的代码.

The reason it's neater is that there is no doubt about what type is expected, and you aren't forced to guess at what the caller intended for you to do with the datatype it gave you. The problem with isinstance(x, basestring) is that there is no way for the caller to tell you, for instance, that even though the type is not a basestring, you should treat it as a string (and not another sequence.) And perhaps the caller would like to use the same type for different purposes, sometimes as a single item, and sometimes as a sequence of items. Being explicit takes all doubt away and leads to more robust and clearer code.