ChatGPT解决这个技术问题 Extra ChatGPT

在 Python 中不能定义多个构造函数吗? [复制]

这个问题在这里已经有了答案:12 年前关闭。

可能重复:在 Python 中拥有多个构造函数的干净、pythonic 方式是什么?

不能在 Python 中定义多个具有不同签名的构造函数吗?如果没有,绕过它的一般方法是什么?

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

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

让我想到这个问题 - stackoverflow.com/questions/682504/…
基于标题和正文的关系,这个问题具有误导性。更糟糕的是,它似乎是谷歌的最佳答案;我希望它被编辑或删除,因为正文中的问题是非常基本的东西。标题的答案可以在可能的重复链接中找到。

A
Andrew Sledge

与 Java 不同,您不能定义多个构造函数。但是,如果未通过,您可以定义默认值。

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

N
Neuron

如果您的签名仅在 number 个参数上有所不同,则使用默认参数是正确的方法。如果您希望能够传入不同的参数种类,我会尽量避免另一个答案中提到的基于 isinstance 的方法,而是使用关键字参数。

如果只使用关键字参数变得笨拙,您可以将其与类方法结合使用(bzrlib 代码喜欢这种方法)。这只是一个愚蠢的例子,但我希望你明白:

class C(object):

    def __init__(self, fd):
        # Assume fd is a file-like object.
        self.fd = fd

    @classmethod
    def from_filename(cls, name):
        return cls(open(name, 'rb'))

# Now you can do:
c = C(fd)
# or:
c = C.from_filename('a filename')

请注意,所有这些类方法仍然通过相同的 __init__,但使用类方法比必须记住 __init__ 的关键字参数组合的工作方式要方便得多。

最好避免使用 isinstance,因为 Python 的鸭子类型很难确定实际传入的是哪种对象。例如:如果您想获取文件名或类似文件的对象,则不能使用 isinstance(arg, file),因为有许多类似文件的对象不是 file 的子类(例如从 urllib、StringIO 或...返回的对象)。通过使用不同的关键字参数,让调用者明确地告诉你是什么类型的对象通常是一个更好的主意。


正如您所说,如果您需要传递不同类型的参数,这是一个很好的方法。在这些情况下,我倾向于使用非常基本的 __init__ 并为每种情况创建多个类方法。
这是最普遍适用的解决方案
有没有一种好方法(您的建议)不从第二个构造函数运行通常的 __init__ 函数?例如,因为两者都会从头开始构造对象
N
Neuron

对于您给出的示例,请使用默认值:

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

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

根据类型执行 if-elif 块: def __init__(self, name): if isinstance(name, str): # todo elif isinstance(name, City): # todo # todo 使用鸭子类型 - 即假设用户你班上的学生足够聪明,可以正确使用它。这通常是首选选项。


N
Neuron

answer by 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

>>>

P
Peter Mortensen

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

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

someCity = City(city="Berlin")

这是非常基本的东西。也许看看the Python documentation


评论中的错别字;另外,这不是他问的问题——他问的是关于切换类型的问题,他只是提供了一个不好的例子。
@pavpanchekha:这正是所要求的。除了当然缺少 self
@Jack,您的示例实际上也没有将 city 存储在任何地方,因此对于新手来说,这可能是一个非常令人困惑的答案。