Last active
May 5, 2018 19:27
-
-
Save jakab922/6130481 to your computer and use it in GitHub Desktop.
Python metaclass reminder
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class MetaClass(type): | |
counter = 1 | |
def __new__(meta, name, bases, dct): | |
""" Gets called when we read in the class definition for which this is the metaclass of""" | |
print "MetaClass.__new__(%s, %s, %s, %s)" % (meta, name, bases, dct) | |
dct['class_num'] = meta.counter | |
meta.counter += 1 | |
return super(MetaClass, meta).__new__(meta, name, bases, dct) | |
def __init__(cls, name, bases, dct): | |
""" Gets called when we read in the class definition for which this is the metaclass of and after __new__ | |
of the metaclass.""" | |
print "MetaClass.__init__(%s, %s, %s, %s)" % (cls, name, bases, dct) | |
return super(MetaClass, cls).__init__(name, bases, dct) | |
def __call__(cls, *args, **kwargs): | |
""" Called when an object is created from the class of which this is a metaclass of. args,kwargs are the normal | |
init params""" | |
print "MetaClass.__call__(%s, %s, %s)" % (cls, args, kwargs) | |
return type.__call__(cls, *args, **kwargs) | |
class NormalClass(object): | |
__metaclass__ = MetaClass | |
def __new__(cls, *args, **kwargs): | |
""" Called when class is instantiated and after the metaclasses __call__ method. """ | |
print "NormalClass.__new__(%s, %s, %s)" % (cls, args, kwargs) | |
return super(NormalClass, cls).__new__(cls, *args, **kwargs) | |
def __init__(self, *args, **kwargs): | |
""" Called after meta.__call__ and normal.__new__ on the class returned by __new__""" | |
print self.class_num | |
print "NormalClass.__init__(%s, %s, %s)" % (self, args, kwargs) | |
class OtherNormalClass(object): | |
__metaclass__ = MetaClass | |
def __new__(cls, *args, **kwargs): | |
print "OtherNormalClass.__new__(%s, %s, %s)" % (cls, args, kwargs) | |
return super(OtherNormalClass, cls).__new__(cls, *args, **kwargs) | |
def __init__(self, *args, **kwargs): | |
print self.class_num | |
print "OtherNormalClass.__init__(%s, %s, %s)" % (self, args, kwargs) | |
if __name__ == "__main__": | |
norm1 = NormalClass(5, a=2) | |
norm2 = NormalClass(6, a=3) | |
other1 = OtherNormalClass(7, a=12) | |
""" | |
Call orders with first params in brackets. | |
Call order on reading the class definition: | |
meta.__new__(meta), meta.__init__(class) | |
Call order on the class instantiation: | |
meta.__call__(class), class.__new__(class), class.__init__(self) | |
Call order when we call an instance: | |
class.__call__(self) | |
""" | |
"""TODO: | |
- Look up what the various methods should return and how does that effect the whole procedure. | |
- Maybe a full call graph to make this a bit cleaner. | |
""" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment