Skip to content

Instantly share code, notes, and snippets.

@pahaz
Created March 11, 2016 13:15
Show Gist options
  • Save pahaz/70ce16ee37f35bc12429 to your computer and use it in GitHub Desktop.
Save pahaz/70ce16ee37f35bc12429 to your computer and use it in GitHub Desktop.
EXAMPLE! How to understand the python metaclasses. Less1.
from functools import wraps
def debug(func):
print('debug(', func.__qualname__, ')')
name = func.__qualname__
@wraps(func)
def wrapper(*args, **kwargs):
print('CALL:', name, args, kwargs)
return func(*args, **kwargs)
return wrapper
def debugclass(cls):
print('debugclass(', cls.__qualname__, ')')
for name, val in vars(cls).items():
if callable(val):
setattr(cls, name, debug(val))
return cls
class debugmeta(type):
def __new__(cls, clsname, bases, clsdict):
print('CONSTRUCT NEW CLASS:', clsname, bases, clsdict)
clsobj = super().__new__(
cls, clsname, bases, clsdict
)
clsobj = debugclass(clsobj)
return clsobj
print(1)
class Base(object, metaclass=debugmeta):
def foo(self):
pass
print(2)
class A(Base):
@staticmethod
def __new__(cls, *args, **kwargs):
print('CONSTRUCT NEW INSTANCE:', cls, args, kwargs)
return super().__new__(cls, *args)
def bar(self):
pass
print(3)
a = A()
a.foo()
a.bar()
print(4)
# output:
"""
1
CONSTRUCT NEW CLASS: Base (<class 'object'>,) {'__qualname__': 'Base', 'foo': <function Base.foo at 0x025264F8>, '__module__': '__main__'}
debugclass( Base )
debug( Base.foo )
2
CONSTRUCT NEW CLASS: A (<class '__main__.Base'>,) {'__qualname__': 'A', 'bar': <function A.bar at 0x0256FA08>, '__module__': '__main__', '__new__': <staticmethod object at 0x02535170>}
debugclass( A )
debug( A.bar )
3
CONSTRUCT NEW INSTANCE: <class '__main__.A'> () {}
CALL: Base.foo (<__main__.A object at 0x02535630>,) {}
CALL: A.bar (<__main__.A object at 0x02535630>,) {}
4
"""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment