您问的是两个经常混淆的话题:初始化器__init__ 和构造器__new__。另外,我认为您将 Python 与 Java 之类的语言混淆了,其中构造函数很重要,不像其他语言,构造和初始化混合在一个进程中(因此对于 Python 新手来说是一个常见的误解)。
在 Python 中,构造器和初始化器都是方法,与任何其他方法没有区别。有一个命名约定,即(某些)两端带有双下划线的方法将由解释器调用,而无需您显式执行,但如果您愿意,您可以自己调用它们,并且您会得到相同的结果。
简而言之:如果你了解__str__,你就了解__init__和__new__。
(我认为对于一些有经验的程序员来说,Python 最奇怪的地方在于它不会每时每刻都用特殊情况埋伏你。)
方法解析顺序
Python 2.3 的 new-style classes 从对象的类开始查找方法名称,然后遍历该类的祖先,直到找到要查找的名称或用完要搜索的类。
您可以通过查看其__mro__ 字段来查看任何类的方法解析顺序:
>>> TestClass.__mro__
(<class '__main__.TestClass'>, <class 'object'>)
>>> float.__mro__
(<class 'float'>, <class 'object'>)
>>> object.__mro__
(<class 'object'>,)
(Python 使用C3 Method Resolution Order algorithm 构造元组,但对于像您这样的简单情况来说,它是多余的。C3 主要关注将复杂的多继承图线性化为可以按可预测顺序搜索的类元组.)
任何方法查找,即使是__init__ 或__new__,都遵循方法解析顺序。对于元组中的每个类,Python 在其类__dict__ 中查找字符串(如'__init__');如果该字符串存在,则其关联值 --- 无论它是什么 --- 都将作为方法查找的结果返回。
在您的情况下,Python 会查找不存在的TestClass.__new__,然后查找存在的object.__new__。然后它执行object.__new__(自动填写一些参数)来构造你的新TestClass对象。使用__init__ 进行初始化是相同的,只是您可以自己提供一些额外的参数。
证明(在 Python 3 中):
>>> class A: pass
...
>>> A.__init__ is object.__init__
True
>>> A.__new__ is object.__new__
True
>>> A.__repr__ is object.__repr__
True
>>> A.__str__ is object.__str__
True
__init__的参数
您尝试将参数传递给object.__init__ 失败,因为该方法不接受任何参数(self 除外,它已为您填写)。它看起来或多或少是这样的:
class Object:
def __init__(self):
return
结论
Python 不会像 (IIRC) Java 那样为您的类“创建”默认构造函数或初始化程序。但它在 object 类中各有一个,所以如果你不自己写,你会继承它们。