I'd like to automatically run some code upon class creation that can call other class methods. I have not found a way of doing so from within the class declaration itself and end up creating a @classmethod called __clsinit__ and call it from the defining scope immediately after the class declaration. Is there a method I can define such that it will get automatically called after the class object is created?
            Asked
            
        
        
            Active
            
        
            Viewed 6,387 times
        
    13
            
            
         
    
    
        Eldar Abusalimov
        
- 24,387
- 4
- 67
- 71
 
    
    
        Simon
        
- 133
- 1
- 5
- 
                    2Class creation or instance creation? Because both can be done, but the answer is different depending. – Silas Ray Aug 24 '12 at 19:15
- 
                    1You can use metaclasses for this. See for instance [this question](http://stackoverflow.com/questions/100003/what-is-a-metaclass-in-python). – BrenBarn Aug 24 '12 at 19:16
- 
                    9Aside: Please don't make up `__special_methods__`. That's reserved for the Python language. Use a `_single_underscore_prefix` if you want it to be private. – Aug 24 '12 at 19:17
2 Answers
20
            You can do this with a metaclass or a class decorator.
A class decorator (since 2.6) is probably easier to understand:
def call_clsinit(cls):
    cls._clsinit()
    return cls
@call_clsinit
class MyClass:
    @classmethod
    def _clsinit(cls):
        print "MyClass._clsinit()"
Metaclasses are more powerful; they can call code and modify the ingredients of the class before it is created as well as afterwards (also, they can be inherited):
def call_clsinit(*args, **kwargs):
    cls = type(*args, **kwargs)
    cls._clsinit()
    return cls;
class MyClass(object):
    __metaclass__ = call_clsinit
    @classmethod
    def _clsinit(cls):
        print "MyClass._clsinit()"
 
    
    
        ecatmur
        
- 152,476
- 27
- 293
- 366
- 
                    2I'd add that at least from the text of the question, it's hard to tell why `__new__` or `__init__` don't do the trick. – Silas Ray Aug 24 '12 at 19:32
