Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

python

oop

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

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:

    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: __init__() should return None, not 'int'

Why is there a problem?

like image 361
user1592380 Avatar asked Apr 16 '16 15:04

user1592380


People also ask

Should init return None?

The __init__ method of a class is used to initialize new objects, not create them. As such, it should not return any value. Returning None is correct in the sense that no runtime error will occur, but it suggests that the returned value is meaningful, which it is not.

What is the purpose of the __ init __ method?

The __init__ method lets the class initialize the object's attributes and serves no other purpose. It is only used within classes.


1 Answers

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 @CPanda did not do the opposite of what he said. That is why I want to highlight this again as answer:

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 TypeError to be raised at runtime.

So do NOT return values using __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 Exceptions for more information)

like image 160
Billal Begueradj Avatar answered Sep 19 '22 12:09

Billal Begueradj