How to return a value from __init__ in Python?
__init__
is required to return None. You cannot (or at least shouldn't) return something else.
Try making whatever you want to return an instance variable (or function).
>>> class Foo:
... def __init__(self):
... return 42
...
>>> foo = Foo()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: __init__() should return None
What does __init__ method return in python
__init__()
returns None
. It is __new__()
that returns the new instance.
Why is that __init__ function of python doesn't have a return statement even though its a function
__init__()
is not a normal function. It is a special method Python uses to customize an instance of a class. It is part of Python's data model:
Called after the instance has been created (by
__new__()
), but before it is returned to the caller[...].
As you can see from above, when you create a new instance of a class, Python first calls __new_()
- which is also a special method - to create a new instance of the class. Then __init__()
is called to customize the new instance.
It wouldn't make sense to return anything from __init__()
, since the class instance is already created. In fact, Python goes as far as raising an error to prevent this:
>>> class A:
... def __init__(self):
... return 'foo'
...
>>> A()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: __init__() should return None, not 'str'
>>>
If you want to know what exactly is going on behind the scenes, @eryksun provides a nice explanation:
To completely explain this story, you have to step back to the metaclass
__call__
method. In particular the defaulttype.__call__
in CPython calls__new__
and__init__
via their C slot functions, and it'sslot_tp_init
(defined in Objects/typeobject.c) that enforces the return value to be None. If you use a custom metaclass that overridestype.__call__
, it can manually call the__new__
and__init__
methods of the class with no restriction on what__init__
can return -- as silly as that would be.
How can I change what __init__ returns?
The __init__
method doesn't actually return the new instance; when you construct an object by writing Foo()
you are not calling __init__
directly, you are calling __new__
, and the __new__
method initialises the instance by calling __init__
. So you can change what Foo()
returns by overriding __new__
:
class Foo:
def __new__(cls):
obj = super().__new__(cls)
obj.__init__()
return obj.some_method()
def __init__(self):
self.x = 5
def some_method(self):
return self.x * 2
print(Foo()) # 10
Alternatively you can use a class decorator to replace Foo
with a function which creates the instance, calls the method and returns the result:
from functools import wraps
def autocall(cls):
@wraps(cls)
def wrapped():
obj = cls()
return obj.some_method()
return wrapped
@autocall
class Foo:
def __init__(self):
self.x = 5
def some_method(self):
return self.x * 2
print(Foo()) # 10
That said, it's almost always better to just write a helper function, so that the class Foo
can still be used in the normal way for other purposes (e.g. testing):
class Foo:
def __init__(self):
self.x = 5
def some_method(self):
return self.x * 2
def foo_helper():
obj = Foo()
return obj.some_method()
print(foo_helper()) # 10
Bad form to return None in __init__ in python
For any function, not only __init__
, using plain return
is equivalent to returning None
, and if you don't use return
in a function, None
is implicitly returned anyway.
Therefor, it is perfectly fine to use return
inside __init__
.
(The exception to the rule above is generator functions, inside which you may only use return
and not return None
, so these are not equivalent inside generator functions).
Returning in the middle of __init__
will simply cut off object's initialization. It will not prevent the object from being created, nor interrupt program's flow in any way.
Will python class __init__ method implicitly return None?
Strictly speaking, it's not A.__new__()
that's creating the the instance a
.
When you define class A(object):
(or class A:
as well if you are using Python3, class A:
is the old-style class that has been deprecated), it is __new__
from the inheritedobject.__new__()
that is being called to create the instance a
.
When a = A()
is executed, what happens is:
A()
is a shorthand forA.__call__
object.__new__(cls, *args, **kwargs)
wherecls=A
, is what actually happens under hood to create instancea
. It allocates the memory for the new object, and should then return a new object (the instance).- if and only if the newly created object is returned does
__init__(self)
then get called with the newly created object passed to it to "initilize" the object.
Consider the following demo:
when we override
__new__
and no longer returns an object,__init__
will
not get called:class A(object):
def __new__(cls, *args, **kwargs):
print cls, args, kwargs
def __init__(self):
self.x = 'init!'
print self.x
In : a = A()
<class '__main__.A'> () {}
# note that "init!" has not appeared here because __new__ didn't return an
# new instancenow, return a new instance by using
object.__new__
, and you will see that
after__new__
,__init__
would be called as well:class A(object):
def __new__(cls, *args, **kwargs):
print cls, args, kwargs
return object.__new__(cls, args, kwargs)
def __init__(self):
self.x = 'init!'
print self.x
In : a = A()
<class '__main__.A'> () {}
init!
Here is another demo to display the difference, note that instance a
can be created without calling __init__()
:
class A(object):
def __init__(self):
self.x = "init!"
print self.x
In : a = object.__new__(A)
In : a
Out: <__main__.A at 0x103466450>
In : a.__dict__
Out: {}
In : aa = A()
init!
In : aa
Out: <__main__.A at 0x1033ddf50>
In : aa.__dict__
Out: {'x': 'init!'}
Now for the inquisitive (and also to refresh my own memory =]):
Roughly speaking, there are two main ways to create new objects in Python:
Create new object (type / class) by subclassing:
class
statements tells Python to create a new type / class object(by
subclassing an existing type/class such as object
):
class Hello(object):
pass
>>> Hello.__class__
<type 'type'>
In fact all class/type object have type type
. The type of type
(type(type)
) is still type.
You can subclass a type / class object.
Create new object (instance) by instantiating:
You can also create a new object by instatiating an existing type object.
This is done via the using the __call__
operator (shorthand by ()
):
>>> h = hello()
>>> type(h)
<class '__main__.Hello'>
>>> type(int('1'))
<type 'int'>
You cannot subclass an instance object.
(note that you can also create a new instance object by some other means such
as using the list operator [1,2,3]
, in this case it creates an list instance)
You can check an object's type by type(my_obj)
or my_object.__class__
.
Now you know how an instance object is created, but what really creates the type / class object (that allows to create instance objects)?
In fact, these objects are created by instantiation as well, albeit it is a
slightly different kind of instantiation from what was mentioned earlier.
Aside from class
statement, you can also use type(cls_name, parent_class_tuple, attr_dict)
to create a new class.
For eg:
type('Hello', (object,), {})
will create the Hello
class same as the one shown earlier.
What is type
? Enter metaclass.
type
is a metaclass, which is the class of class, i.e., classes are
instances of metaclasses. The __class__
of type
is still type
.
So here is a graph that shows the relationships between metaclass, class,
instance:
instantiate instantiate
metaclass --------------> class ----------------> instance
type.__new__() object.__new__()
When metaclass type
is called to create a new class, the similar flow goes:
type.__call__()
is excutedtype.__new__()
allocates memory and then returns new a class (a metaclass instace), and then callstype.__init__()
.type.__init__()
initalizes the newly created class that was passed from step 2.
You can even create a new metaclass by subclassing type
:
class MyMeta(type):
def __new__(meta, name, bases, dct):
# do something
return super(MyMeta, meta).__new__(meta, name, bases, dct)
def __init__(cls, name, bases, dct):
# do something
super(MyMeta, cls).__init__(name, bases, dct)
then you can create a new class from this MyMeta
metaclass just like you do
with type
:
MyClass = MyMeta('MyClass', (object, ), {'x': 1})
Or, use __metaclass__
when defining your class, which has exactly the
same effect as what was shown above:
class MyClass(object):
__metaclass__ = MyMeta
x = 1
Related Topics
Cosine Similarity Between 2 Number Lists
Call Python Function from Matlab
How to Take Partial Screenshot with Selenium Webdriver in Python
How to Avoid Http Error 429 (Too Many Requests) Python
How to Access the Request Object or Any Other Variable in a Form's Clean() Method
How to Exchange Keys with Values in a Dictionary
Running an Outside Program (Executable) in Python
Is There a Function That Checks If a Character in a String Is a Letter in the Alphabet? (Swift)
Function Which Returns the Least-Squares Solution to a Linear Matrix Equation
Extract Column Value Based on Another Column Pandas Dataframe
How to Add Title to Subplots in Matplotlib
Create Dynamic Urls in Flask with Url_For()
How to Import CSV Data into Django Models
Dead Simple Example of Using Multiprocessing Queue, Pool and Locking
How to Convert a Dictionary into a List of Tuples
Get Protocol + Host Name from Url