如果您的问题因与此问题重复而被关闭,那是因为您有一个代码示例,其中包含以下内容:
class Example: def __int__(self, parameter): self.attribute = parameter
或者:
class Example: def _init_(self, parameter): self.attribute = parameter
当您随后尝试创建该类的实例时,会发生错误:
>>> Example("an argument") Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: Example() takes no arguments
(在某些版本的 Python 中,错误可能会改为显示TypeError: object.__new__() takes no parameters。)
TypeError: object.__new__() takes no parameters
或者,该类的实例似乎缺少属性:
>>> class Example: ... def __int__(self): # or _init_ ... self.attribute = 'value' >>> Example().attribute Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'Example' object has no attribute 'attribute'
您可能还想知道:这些异常消息是什么意思,它们与问题有何关系?为什么问题没有更早出现(例如,类定义本身)?问题还会以其他方式表现出来?我如何防范将来出现此问题?
这是因为代码有一个简单的印刷错误:该方法应该被命名__init__- 请注意拼写,并注意两边都有两个下划线。
__init__
正如人们可能猜到的那样,aTypeError是与某种类型有关的错误。在这种情况下,其含义有点牵强:Python还将此错误类型用于函数调用,其中参数(为了调用函数、类构造函数或其他可调用函数而放在中间的东西)无法正确分配给参数(使用语法编写函数时放在中间的东西)。()``()``def
TypeError
()``()``def
在出现 a 的示例中TypeError,类的构造函数Example不接受参数。为什么?因为它使用的是不接受参数的基object构造函数。这只是遵循了正常的继承规则:没有本地定义,因此使用__init__超类中的构造函数(在本例中)。object
Example
object
类似地,AttributeError是与某事物的属性有关的错误。这很简单: 的实例没有任何属性,因为构造函数(再次,由于拼写错误而来自)没有设置属性。Example``.attribute``object
AttributeError
Example``.attribute``object
因为方法名输入错误在语法上仍然有效。SyntaxError在代码运行之前只能捕获语法错误(报告为)。Python 不会为命名的方法_init_(两边各有一个下划线)赋予任何特殊含义,因此它不关心参数是什么。虽然__int__用于将类的实例转换为整数,并且除了之外不应有任何参数self,但它在语法上仍然有效。
SyntaxError
_init_
__int__
self
您的 IDE 可能会警告您某个__int__方法采用了可疑参数(即除 之外的任何参数self)。但是,a) 这并不能完全解决问题(见下文),并且 b) IDE 可能一开始就帮助您犯了错误(通过提供错误的自动完成建议)。
如今,这种_init_拼写错误似乎已经不那么常见了。我猜人们以前在阅读排版糟糕的书籍示例代码后就会犯这种错误。
如果成功创建了实例(但未正确初始化),则以后可能会发生任何类型的问题(取决于需要正确初始化的原因)。例如:
BOMB_IS_SET = True class DefusalExpert(): def __int__(self): global BOMB_IS_SET BOMB_IS_SET = False def congratulate(self): if BOMB_IS_SET: raise RuntimeError("everything blew up, gg") else: print("hooray!") >>> d = DefusalExpert() >>> d.congratulate() Traceback (most recent call last): ... RuntimeError: everything blew up, gg
如果您希望该类可转换为整数,并且也__int__特意这样写,则最后一个将优先:
class LoneliestNumber: def __int__(self): return 1 def __int__(self): # was supposed to be __init__ self.two = "can be as bad" >>> int(LoneliestNumber()) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: __int__ returned non-int (type NoneType)
没有灵丹妙药。我发现,如果类需要的话,将__init__(and/or __new__) 作为类中的第一个方法的惯例会有所帮助。但是,校对或培训是无可替代的。
__new__