Chr*_*ris 200 python constructor
是否不可能在Python中定义具有不同签名的多个构造函数?如果没有,绕过它的一般方法是什么?
例如,假设您想要定义一个类 City
我想能够说,someCity = City()
或者someCity = City("Berlin")
,第一个只提供默认名称值,第二个定义它.
And*_*dge 274
与Java不同,您无法定义多个构造函数.但是,如果未传递默认值,则可以定义默认值.
def __init__(self, city="Berlin"):
self.city = city
Run Code Online (Sandbox Code Playgroud)
mzz*_*mzz 224
如果您的签名仅使用默认参数的参数数量不同是正确的方法.如果你想能够传递不同类型的参数,我会尽量避免isinstance
在另一个答案中提到的基于方法的方法,而是使用关键字参数.如果仅使用关键字参数变得难以处理,则可以将其与classmethods结合使用(bzrlib代码喜欢这种方法).这只是一个愚蠢的例子,但我希望你明白这个想法:
class C(object):
def __init__(self, fd):
# Assume fd is a file-like object.
self.fd = fd
@classmethod
def fromfilename(cls, name):
return cls(open(name, 'rb'))
# Now you can do:
c = C(fd)
# or:
c = C.fromfilename('a filename')
Run Code Online (Sandbox Code Playgroud)
请注意所有这些类方法仍然是相同的__init__
,但使用classmethods比记住要使用的关键字参数组合要方便得多__init__
.
isinstance
最好避免使用python的duck typing使得很难弄清楚实际传入的是什么类型的对象.例如:如果你想要一个文件名或类文件对象你不能使用,isinstance(arg, file)
因为有很多类似文件的对象不是子类file
(如从urllib,StringIO或...返回的子类).通过使用不同的关键字参数,让调用者明确告诉您对象的含义通常是一个更好的主意.
对于您提供的示例,请使用默认值:
class City:
def __init__(self, name="Default City Name"):
...
...
Run Code Online (Sandbox Code Playgroud)
通常,您有两种选择:
1)Do if
- elif
基于类型的块:
def __init__(self, name):
if isinstance(name, str):
...
elif isinstance(name, City):
...
...
Run Code Online (Sandbox Code Playgroud)
2)使用duck typing ---也就是说,假设你的类的用户足够聪明,可以正确使用它.这通常是首选方案.
最简单的方法是通过关键字参数:
class City():
def __init__(self, city=None):
pass
someCity = City(city="Berlin")
Run Code Online (Sandbox Code Playgroud)
这是非常基本的东西,也许看看python文档?
杰克 M. 是对的。这样做:
>>> class City:
... def __init__(self, city=None):
... self.city = city
... def __repr__(self):
... if self.city: return self.city
... return ''
...
>>> c = City('Berlin')
>>> print c
Berlin
>>> c = City()
>>> print c
>>>
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
208836 次 |
最近记录: |