Python 类型错误:__init__() 应该返回 None,而不是 'int'

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36666353/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 18:11:58  来源:igfitidea点击:

TypeError: __init__() should return None, not 'int'

pythonoop

提问by user61629

I'm working through this tutorial. I'm working through this iteratively. At this point I have the following Binary class:

我正在学习本教程。我正在迭代地解决这个问题。此时我有以下 Binary 类:

class Binary:
    def __init__(self,value):
        self.value = str(value)
        if self.value[:2] == '0b':
            print('a binary!')
            self.value= int(self.value, base=2)
        elif self.value[:2] == '0x':
            print('a hex!')
            self.value= int(self.value, base=16)
        else:
            print(self.value)
        return int(self.value)

I'm running through a suite of tests using pytest, including:

我正在使用 pytest 运行一套测试,包括:

    def test_binary_init_hex():
        binary = Binary(0x6)
        assert int(binary) == 6
      E TypeError: int() argument must be a string or a number, not 'Binary'

I asked a question about this TypeError: int() argument must be a string or a number, not 'Binary'and based on the answer changed the code to as above. Now when I run the suite of tests using pytest, all the tests fail and the error is:

我问了一个关于这个TypeError的问题:int() 参数必须是字符串或数字,而不是 'Binary'并根据答案将代码更改为如上。现在,当我使用 pytest 运行测试套件时,所有测试都失败了,错误是:

       TypeError: __init__() should return None, not 'int'

Why is there a problem?

为什么会出现问题?

回答by Billal Begueradj

Before any answer was provided, I commented you that __init__()is used to initialize objects and thus you must not return any value within it. But it is strange to see some of the upvoted answers above asked not to return values within __init__()but still their solution does not respect what they said. Only @CPandadid not do the opposite of what he said. That is why I want to highlight this againas answer:

在提供任何答案之前,我评论了您__init__()用于初始化对象,因此您不得返回其中的任何值。但是很奇怪看到上面的一些赞成的答案要求不要返回其中的值,__init__()但他们的解决方案仍然不尊重他们所说的。只有@CPanda没有做与他所说的相反的事情。这就是为什么我想再次强调这一点作为答案:

Called after the instance has been created (by __new__()), but before it is returned to the caller. The arguments are those passed to the class constructor expression. If a base class has an __init__()method, the derived class's __init__()method, if any, must explicitly call it to ensure proper initialization of the base class part of the instance; for example: BaseClass.__init__(self, [args...]).

Because __new__()and __init__()work together in constructing objects (new() to create it, and __init__()to customise it), no non-None value may be returned by __init__(); doing so will cause a TypeErrorto be raised at runtime.

在创建实例之后(由__new__())调用,但在它返回给调用者之前调用。参数是传递给类构造函数表达式的参数。如果基类有__init__()方法,则派生类的__init__()方法(如果有)必须显式调用它以确保正确初始化实例的基类部分;例如:BaseClass.__init__(self, [args...]).

因为__new__()__init__()一起构建对象(new() 来创建它,并__init__()定制它),没有非 None 值可能被返回__init__();这样做会导致 a TypeError在运行时被引发。

So do NOT return values using __init__()!

所以不要使用__init__()!

An other thing I want to add, even if this is not mentioned AFAIK in Python Enhancement Proposals, I personally never use __init__()to print messages using print''/print(''). The only messages I print in __init__()are those related to raised exception error messages in a forms such as raise ValueError()(check Built-in Exceptionsfor more information)

我想补充的另一件事,即使在Python Enhancement Proposals 中没有提到 AFAIK ,我个人也从不使用/__init__()打印消息。我打印的唯一消息 是与引发的异常错误消息相关的消息,例如(检查内置异常以获取更多信息)print''print('')__init__()raise ValueError()

回答by cdarke

The documentationstates:

文件指出:

"Because __new__()and __init__()work together in constructing objects (__new__()to create it, and __init__()to customise it), no non-None value may be returned by __init__(); doing so will cause a TypeError to be raised at runtime."

因为__new__()__init__()一起工作在构建对象(__new__()创建它,并__init__()对其进行自定义),没有非无值可以通过返回__init__();这样做将导致一个TypeError在运行时提出的。

So remove that returnstatement and place it in an __int__method in your class:

因此,删除该return语句并将其放在__int__类中的一个方法中:

def __int__(self):
    return int(self.value)

回答by iAdjunct

__init__initializes an instance of a class (in your case, an instance of Binary). An instance of a class is a specific thingof a specific type.

__init__初始化一个类的实例(在你的情况下,一个实例Binary)。类的实例是特定类型的特定事物

In your case, you seem to be not using it as a typeof thingbut instead as a utility that intelligently converts numbers. You should instead probably just make it a function:

在你的情况,你似乎没有使用它作为一个类型事情,而是作为一个工具,可以智能转换数字。您应该改为将其设为函数:

def binary ( value ) :
    value = str(value)
    if self.value[:2] == '0b':
        print('a binary!')
        value = int(value, base=2)
    elif self.value[:2] == '0x':
        print('a hex!')
        value = int(value, base=16)
    else:
        print(value)
    return int(value)

回答by Daniel

__init__is called, after a instance was created with

__init__在创建实例后调用

obj = SomeClass()

So there is now way to assign any return value to a variable, therefore __init__must not return anything (except implicitly None).

因此,现在可以将任何返回值分配给变量,因此__init__不得返回任何内容(隐式除外None)。

To pass your test, the object should have a magic method __int__, which is called, when the function intis used.

要通过您的测试,该对象应该有一个魔术方法__int__,在使用该函数时会调用该int方法。

回答by C Panda

__init__Cannot return anything other than None. This is because it is the initialiser of an instance created by __new__, both of which are called implicitly when you call the class callable. Hence if you try to return anything yourself from it, a TypeErrorexception is raised.

__init__不能返回除 之外的任何东西None。这是因为它是由创建的实例的初始化程序,__new__当您调用类 callable 时,这两个实例都会被隐式调用。因此,如果您尝试自己从中返回任何内容,TypeError则会引发异常。

Possible solutions are refactor your code in to methods or @propertys and use them later. If you want something more daring checkout metaclasses.

可能的解决方案是将您的代码重构为方法或@propertys 并在以后使用它们。如果你想要更大胆的结账元类。