Metaclasses - magic functions

Mr. Wrobel mr at e-wrobel.pl
Fri Dec 23 06:14:15 EST 2016


W dniu 21.12.2016 o 02:51, Ethan Furman pisze:
> On 12/20/2016 03:39 PM, Ben Finney wrote:
>> "Mr. Wrobel" writes:
>
>>> Quick question, can anybody tell me when to use __init__ instead of
>>> __new__ in meta programming?
>>
>> Use ‘__new__’ to do the work of *creating* one instance from nothing;
>> allocating the storage, determining the type, etc. — anything that will
>> be *the same* for every instance. ‘__new__’ is the constructor.
>>
>> Use ‘__init__’ to do the work of *configuring* one instance, after it
>> already exists. Any attributes that are special to an instance should be
>> manipulated in the ‘__init__’ method. ‘__init__’ is the initialiser.
>
> That sounds like general object creation/class advice, which as a general
> guideline is okay, but don't feel like it's the most important thing.
>
> I only use `__new__` when the object being created is (or is based on)
> an immutable type; otherwise I use `__init__`.  Likewise, if I'm using
> `__new__` then I do all my configuration in `__new__` unless I have a
> really good reason not to (such as making it easier for subclasses to
> modify/skip `__init__`).
>
> As far as metaclasses go... the only time I recall writing an `__init__`
> for a metaclass was to strip off the extra arguments so `type.__init__`
> wouldn't fail.
>
> --
> ~Ethan~
Hi,thanx for answers, let's imagine that we want to add one class 
attribute for newly created classess with using __init__ in metaclass, 
here's an example:

#!/usr/bin/env python

class MetaClass(type):
     # __init__ manipulation:

     def __init__(cls, name, bases, dct):
         dct['added_in_init'] = 'test'
         super(MetaClass, cls).__init__(name, bases, dct)

class BaseClass(object):
     __metaclass__ = MetaClass

class NewBaseClass(BaseClass):
     pass

print("Lets print attributes added in __init__ in base classes:")

print(BaseClass.added_in_init)

print(NewBaseClass.added_in_init)

after running it: AttributeError: type object 'BaseClass' has no 
attribute 'added_in_init'

Adding the same in __new__ works. Can anyone explain me please what's wrong?

Cheers,
M






More information about the Python-list mailing list