TypeError:__ init __()应该返回None,而不是' int'

时间:2016-04-16 15:53:37

标签: python oop

我正在完成这个tutorial。我正在迭代地完成这个工作。此时我有以下二进制类:

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)

我正在使用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'

我问了一个关于这个TypeError: int() argument must be a string or a number, not 'Binary'的问题,并根据答案将代码更改为如上所述。现在,当我使用pytest运行测试套件时,所有测试都失败了,错误是:

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

为什么会有问题?

5 个答案:

答案 0 :(得分:4)

documentation州:

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

请删除该return语句,并将其放入班级的__int__方法中:

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

答案 1 :(得分:4)

在提供任何答案之前,我评论过你__init__()用于初始化对象,因此你不能在其中返回任何值。但令人奇怪的是,上面提到的一些上述答案要求不要在__init__() b内返回值,但他们的解决方案仍不符合他们所说的内容。只有@CPanda与他所说的相反。这就是我想highlight this again作为答案的原因:

  

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

     

由于__new__()__init__()在构建对象(()以创建对象,以及__init__()自定义对象)中协同工作,所以   { - 1}}可能会返回非无值;这样做会导致   __init__()将在运行时引发。

所以不要使用TypeError返回值!

我要添加的其他内容,即使在 Python Enhancement Proposals 中未提及AFAIK,我个人也从未使用__init__()来使用__init__()打印消息/ print''。我在print('')中打印的唯一消息是与raise ValueError()等格式中引发的异常错误消息相关的消息(有关详细信息,请查看Built-in Exceptions

答案 2 :(得分:3)

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

在您的情况下,您似乎没有将其用作 thing 类型,而是用作智能转换数字的实用程序。你可能应该只是使它成为一个函数:

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)

答案 3 :(得分:2)

在使用

创建实例后调用

<?php // include function files for this application require_once('bookmark_fns.php'); //create short variable names $email=$_POST['email']; $username=$_POST['username']; $passwd=$_POST['passwd']; $passwd2=$_POST['passwd2']; // start session which may be needed later // start it now because it must go before headers session_start(); try { // check forms filled in if (!filled_out($_POST)) { throw new Exception('You have not filled the form out correctly. Please go back and try again.'); } // email address not valid if (!valid_email($email)) { throw new Exception('That is not a valid email address. Please go back and try again.'); } // passwords not the same if ($passwd != $passwd2) { throw new Exception('The passwords you entered do not match. Please go back and try again.'); } // check password length is ok // ok if username truncates, but passwords will get // munged if they are too long. if (!preg_match('/^(?=.*\d)(?=.*[A-Za-z])[0-9A-Za-z]{6,12}$/)', $passwd)) { throw new Exception('Your password must be between 6 and 12 characters inclusive. Please go back and try again.'); } // attempt to register // this function can also throw an exception register($username, $email, $passwd); // register session variable $_SESSION['valid_user'] = $username; // provide link to members page do_html_header('Registration successful'); echo "Welcome " $_POST["username"]; echo 'Your registration was successful. Go to the members page to start setting up your bookmarks!'; do_html_url('member.php', 'Go to members page'); // end page do_html_footer(); } catch (Exception $e) { do_html_header('Warning:'); echo $e->getMessage(); do_html_footer(); exit; } ?>

__init__

所以现在有办法为变量赋值,因此obj = SomeClass() 不能返回任何内容(隐式__init__除外)。

要通过测试,当使用函数None时,对象应该有一个魔术方法__int__,该方法被调用。

答案 4 :(得分:2)

<div> Enter your mail: <input TextBox ID="TextBox1" runat="server" ontextchanged="TextBox1_TextChanged"><TextBox/> </div> <div> <Button type="Button" onclick="Ascii('TextBox1')">Convert to ASCII</button> </div> <div> Output: <input TextBox ID="TextBox2" runat="server" ontextchanged="TextBox2_TextChanged"><TextBox/> </div> <script type="text/javascript"> function Ascii(TextBox1) { var val = document.getElementById(TextBox1).value; alert(val.charCodeAt(0)); document.getElementById('TextBox2').value = val.charCodeAt(0); } function StringToAscii(TextBox1) { var val = document.getElementById(TextBox1).value; for(var i = 0; i < val.length; i++) { document.getElementById('TextBox2').value += val.charCodeAt(i); } } </script> 除了__init__之外,不能返回任何内容。这是因为它是None创建的实例的初始化者,当您调用类可调用时,这两个实例都会被隐式调用。因此,如果您尝试从中返回任何内容,则会引发__new__异常。

可能的解决方案是将代码重构为方法或TypeError并稍后使用它们。如果你想要一些更大胆的结账元类。