简体   繁体   English

为什么我的 class 不是由“def __int__”或“def _init_”初始化? 为什么我会收到“不接受参数”类型错误或 AttributeError?

[英]Why isn't my class initialized by "def __int__" or "def _init_"? Why do I get a "takes no arguments" TypeError, or an AttributeError?

If your question was closed as a duplicate of this, it is because you had a code sample including something along the lines of either:如果您的问题与此重复,那是因为您有一个代码示例,其中包含以下任一内容:

class Example:
    def __int__(self, parameter):
        self.attribute = parameter

or:或者:

class Example:
    def _init_(self, parameter):
        self.attribute = parameter

When you subsequently attempt to create an instance of the class, an error occurs:当您随后尝试创建 class 的实例时,会发生错误:

>>> Example("an argument")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Example() takes no arguments

Alternately, instances of the class seem to be missing attributes:或者, class 的实例似乎缺少属性:

>>> 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'

This is because the code has a simple typographical error : the method should instead be named __init__ - note the spelling, and note that there are two underscores on each side.这是因为代码有一个简单的印刷错误:该方法应该命名为__init__ - 注意拼写,并注意每边有两个下划线。

You might also wonder: what do these exception messages mean, and how do they relate to the problem?您可能还想知道:这些异常消息是什么意思,它们与问题有什么关系? Why didn't a problem occur earlier, for example, with the class definition itself?为什么之前没有出现问题,例如 class 定义本身? How else might the problem manifest?问题还可能如何表现? How can I guard against this problem in the future?以后如何防范这个问题?


This is an artificial canonical duplicate created specifically to head off two of the most common typographical errors in code written by new Python programmers.这是一个人工的规范副本,专门用于防止新 Python 程序员编写的代码中两个最常见的印刷错误。 While questions caused by a typo are normally closed for that reason, there are some useful things to explain in this case, and having a duplicate target allows for closing questions faster.虽然由拼写错误引起的问题通常会因此而关闭,但在这种情况下有一些有用的东西需要解释,并且有一个重复的目标可以更快地关闭问题。 I have tried to design the question to be easy to search for.我试图将问题设计为易于搜索。

What do the exception messages mean, and how do they relate to the problem?异常消息是什么意思,它们与问题有什么关系?

As one might guess, a TypeError is an Error that has to do with the Type of something.有人可能会猜到, TypeError是与某事物的Type有关的Error In this case, the meaning is a bit strained: Python also uses this error type for function calls where the arguments (the things you put in between () in order to call a function, class constructor or other "callable") cannot be properly assigned to the parameters (the things you put between () when writing a function using the def syntax).在这种情况下,含义有点紧张:Python将此错误类型用于函数调用,其中参数(您在()之间放置的东西以调用函数、类构造函数或其他“可调用”)不能正确分配给参数(使用def语法编写函数时放在()之间的东西)。

In the examples where a TypeError occurs, the class constructor for Example does not take arguments.在发生TypeError的示例中, Example的类构造函数不带参数。 Why?为什么? Because it is using the base object constructor , which does not take arguments.因为它使用了不带参数的基础object构造函数。 That is just following the normal rules of inheritance: there is no __init__ defined locally, so the one from the superclass - in this case, object - is used.这只是遵循常规的继承规则:本地没有定义__init__ ,因此使用了超类中的那个——在这种情况下,是object

Similarly, an AttributeError is an Error that has to do with the Attribute s of something.同样, AttributeError是与某物的Attribute相关的Error This is quite straightforward: the instance of Example doesn't have any .attribute attribute, because the constructor (which, again, comes from object due to the typo) did not set one.这很简单: Example 的Example没有任何.attribute属性,因为构造函数(同样,由于错字而来自object )没有设置一个。

Why didn't a problem occur earlier, for example, with the class definition itself?为什么没有更早出现问题,例如,类定义本身?

Because the method with a wrongly typed name is still syntactically valid.因为名称输入错误的方法在语法上仍然有效。 Only syntax errors (reported as SyntaxError ; yes, it's an exception, and yes, there are valid uses for it in real programs) can be caught before the code runs.在代码运行之前,只能捕获语法错误(报告为SyntaxError ;是的,这是一个异常,是的,它在实际程序中有有效的用途)可以被捕获。 Python does not assign any special meaning to methods named _init_ (with one underscore on each side), so it does not care what the parameters are. Python 没有为名为_init_的方法赋予任何特殊含义(每边有一个下划线),因此它不关心参数是什么。 While __int__ is used for converting instances of the class to integer, and shouldn't have any parameters besides self , it is still syntactically valid.虽然__int__用于将类的实例转换为整数,并且除了self之外不应有任何参数,但它在语法上仍然有效。

Your IDE might be able to warn you about an __int__ method that takes suspicious parameters (ie, anything besides self ).您的 IDE 可能会就带有可疑参数的__int__方法(​​即除self之外的任何参数)向您发出警告。 However, a) that doesn't completely solve the problem (see below), and b) the IDE might have helped you get it wrong in the first place (by making a bad autocomplete suggestion).但是,a) 这并不能完全解决问题(见下文),并且 b) IDE 可能一开始就帮助您弄错了(通过提出错误的自动完成建议)。

The _init_ typo seems to be much less common nowadays. _init_错字现在似乎不太常见了。 My guess is that people used to do this after reading example code out of books with poor typesetting.我的猜测是,人们过去常常在阅读排版不佳的书籍中的示例代码后这样做。

How else might the problem manifest?问题还可能如何表现?

In the case where an instance is successfully created (but not properly initialized), any kind of problem could potentially happen later (depending on why proper initialization was needed).在成功创建实例(但未正确初始化)的情况下,以后可能会发生任何类型的问题(取决于需要正确初始化的原因)。 For example:例如:

BOMB_IS_SET = True
class DefusalExpert():
    def __int__(self):
        global BOMB_IS_SET
        BOMB_IS_SET = False
    def congratulate(self):
        global BOMB_IS_SET
        if BOMB_IS_SET:
            raise RuntimeError("everything blew up, gg")
        else:
            print("hooray!")

If you intend for the class to be convertible to integer and also wrote __int__ deliberately, the last one will take precedence:如果您打算将该类转换为整数并且还故意写了__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)

(Note that __int__ will not be used implicitly to convert instances of the class to an index for a list or tuple. That's done by __index__ .) (请注意, __int__不会隐式用于将类的实例转换为列表或元组的索引。这是由__index__完成的。)

How might I guard against the problem in the future?以后如何防范这个问题?

There is no magic bullet.没有灵丹妙药。 I find it helps a little to have the convention of always putting __init__ (and/or __new__ ) as the first method in a class, if the class needs one.如果类需要一个方法,我发现始终将__init__ (和/或__new__ )作为类中的第一个方法的约定会有所帮助。 However, there is no substitute for proofreading, or for training.但是,校对或培训是无可替代的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我需要一个 def __init_(self) function 在一个新的 class 定义 - do i need a def __init_(self) function in a new class definition 为什么我在第一个 def 中的第二个 def 不是 function? - Why my second def inside the first def doesn't function? 为什么我的装饰器会收到“TypeError:wrapper() 需要 0 个位置 arguments 但有 2 个给定” - Why do I get "TypeError: wrapper() takes 0 positional arguments but 2 were give" with my decorator 为什么我的“def __str__(self)” function 在 django 中不起作用 - why my “def __str__(self)” function isn't working in django .replace代码为什么不起作用,可能是带有def函数的东西 - Why isn't this .replace code working, It may be something with def function 为什么Python确实输入另一类的定义时不输入它的定义? - Why doesn't Python enter the def of one class while it does enter the def of another? 为什么我的班级代码无法激活,然后在班级中的def在实例中进行一些更改? - why my class code do not activate then def in class make some change in instance? 我该怎么办才能摆脱“ int”对象,这不是我的主函数def模型中的下标错误: - What can I do to get rid of the 'int' object is not subscriptable error in my main function def model: 为什么“class”没有开始像“def”这样的新范围呢? - Why doesn't “class” start a new scope like “def” does? 为什么类有 Def Run() 和 Def Execute()? - Why do classes have Def Run() and Def Execute()?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM