python中的多个构造函数?

时间:2010-01-29 18:38:13

标签: python constructor

  

可能重复:
  What is a clean, pythonic way to have multiple constructors in Python?

是否无法在Python中定义具有不同签名的多个构造函数?如果不是,那么解决它的一般方法是什么?

例如,假设您要定义一个类City

我希望能够说someCity = City()someCity = City("Berlin"),其中第一个只提供默认名称值,第二个定义它。

5 个答案:

答案 0 :(得分:235)

与Java不同,您无法定义多个构造函数。但是,如果未传递默认值,则可以定义默认值。

def __init__(self, city="Berlin"):
  self.city = city

答案 1 :(得分:199)

如果您的签名仅在参数的 number 中有所不同,则使用默认参数是正确的方法。如果您希望能够传递不同的参数,我会尝试避免在另一个答案中提到的基于isinstance的方法,而不是使用关键字参数。如果仅使用关键字参数变得难以处理,则可以将其与c​​lassmethods结合使用(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')

请注意,所有这些类方法仍然使用相同的__init__,但使用classmethods比记住__init__的关键字参数组合更方便。

最好避免使用

isinstance,因为python的duck typing使得很难弄清楚实际传入了什么类型的对象。例如:如果你想要一个文件名或类似文件的对象你就不能使用isinstance(arg, file)因为有许多类文件对象没有子类file(就像从urllib或StringIO返回的那些,或者......)。通过使用不同的关键字参数,通常让调用者明确告诉您对象的含义通常是一个更好的主意。

答案 2 :(得分:6)

对于您提供的示例,请使用默认值:

class City:
    def __init__(self, name="Default City Name"):
        ...
    ...

一般来说,您有两种选择:

1)根据类型执行if - elif个阻止:

def __init__(self, name):
    if isinstance(name, str):
        ...
    elif isinstance(name, City):
        ...
    ...

2)使用duck typing ---也就是说,假设你的类的用户足够聪明,可以正确使用它。这通常是首选方案。

答案 3 :(得分:4)

最简单的方法是通过关键字参数:

class City():
  def __init__(self, city=None):
    pass

someCity = City(city="Berlin")

这是非常基本的东西,也许看看the python docs

答案 4 :(得分:4)

Jack 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

>>>