Skip to content

Instantly share code, notes, and snippets.

@codecats
Last active May 29, 2018 11:40
Show Gist options
  • Save codecats/d166ce754ca4f1250bf30d4250bd5784 to your computer and use it in GitHub Desktop.
Save codecats/d166ce754ca4f1250bf30d4250bd5784 to your computer and use it in GitHub Desktop.
Python object creation - metaclasses
class Meta(type):
@classmethod
def __prepare__(mcs, name, bases, **kwargs):
print(' Meta.__prepare__(mcs=%s, name=%r, bases=%s, **%s)\n' % (
mcs, name, bases, kwargs
))
return {}
def __new__(mcs, name, bases, attrs, **kwargs):
print(' Meta.__new__(mcs=%s, name=%r, bases=%s, attrs=[%s], **%s)\n' % (
mcs, name, bases, ', '.join(attrs), kwargs
))
return super().__new__(mcs, name, bases, attrs) # equals to type.__new__(...)
def __init__(cls, name, bases, attrs, **kwargs):
print(' Meta.__init__(cls=%s, name=%r, bases=%s, attrs=[%s], **%s)\n' % (
cls, name, bases, ', '.join(attrs), kwargs
))
return super().__init__(name, bases, attrs)
def __call__(cls, *args, **kwargs):
print(' Meta.__call__(cls=%s, args=%s, kwargs=%s)\n' % (
cls, args, kwargs
))
return super().__call__(*args, **kwargs)
class Class(metaclass=Meta, extra=1):
def __new__(cls, myarg):
print(' Class.__new__(cls=%s, myarg=%s)\n' % (
cls, myarg
))
return super().__new__(cls)
def __init__(self, myarg):
print(' Class.__init__(self=%s, myarg=%s)\n' % (
self, myarg
))
self.myarg = myarg
return super().__init__()
def __str__(self):
return '<instance of Class; myargs=%s>\n' % (
getattr(self, 'myarg', 'MISSING'),
)
Class(1)
# >>> result
# Meta.__prepare__(mcs=<class '__main__.Meta'>, name='Class', bases=(), **{'extra': 1})
# Meta.__new__(mcs=<class '__main__.Meta'>, name='Class', bases=(), attrs=[__str__, __module__, __init__, __qualname__, __new__], **{'extra': 1})
# Meta.__init__(cls=<class '__main__.Class'>, name='Class', bases=(), attrs=[__str__, __module__, __init__, __qualname__, __new__], **{'extra': 1})
# Meta.__call__(cls=<class '__main__.Class'>, args=(1,), kwargs={})
# Class.__new__(cls=<class '__main__.Class'>, myarg=1)
# Class.__init__(self=<instance of Class; myargs=MISSING>, myarg=1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment