[Tutor] Concept related to python classes

Peter Otten __peter__ at web.de
Tue Sep 8 03:49:59 EDT 2020


Alan Gauld via Tutor wrote:

>> And reflecting on this I suppose one might explicitly call __new__
>> without triggering __init__?
> 
> I'm not 100% sure about this but i think new conventionally
> calls init. ie new creates the new object then calls init on it.
> So it could be the case that if you override new and don't
> call init from new then you could indeed create objects with
> no init. However I have a sneaky suspicion that the meta-programming
> behind classes is more sneaky than that and the init has to
> get called 9things to do with building the object/class
> heirarchy and initialising superclasses etc...)

As I remember it

a = A(...)

is roughly

a = A.__new__(A, ...)
if isinstance(a, A):
   a.__init__()

and this experiment

>>> class A:
...     def __init__(self, *args): print("A.__init____{}".format(args))
... 
>>> class B:
...     def __init__(self, *args): print("B.__init____{}".format(args))
... 
>>> a = A()
A.__init____()
>>> b = B()
B.__init____()
>>> def new(cls, x): return x
... 
>>> A.__new__ = new
>>> A(a)
A.__init____(<__main__.A object at 0x7fdec1336198>,)
<__main__.A object at 0x7fdec1336198>
>>> A(b)
<__main__.B object at 0x7fdec1336160>

seems to confirm that. Creating an object without calling __init__() is as 
easy as (using B as I did not modify its __new__() method)

>>> B.__new__(B)
<__main__.B object at 0x7fdec1336208>

It should do no harm as pickle uses it regularly:

>>> import pickle
>>> data = pickle.dumps(b)
>>> pickle.loads(data)
<__main__.B object at 0x7fdec1336278>




More information about the Tutor mailing list