class Foo:passdef__new__(cls): x =object.__new__(cls) x._secret_attr ="555"return xa_foo = Foo() a_foo._secret_attr
'555'
Note-to-self: psuedo-code steps
by calling type() -> python sees (), looks for type.__call__()
note type.__call__() <——-> type()
or type.__call__(*args, **kwds) <——-> type(*args, **kwds)
inside type.__call__(*args, **kwds)
type.__new__(cls, *args, **kwds)
returns x
type.__init__(x, *args, **kwds)
returns x
6. Customising Class Creation
class TonyMetaClass(type):passdef__new__(cls, name, bases, dcts): x =super().__new__(cls, name, bases, dcts)# calls parents type.__new__()# which is usally called when you instantiate any class# e.g Foo()# 1. () -> python looks for __call__()# 2. find parents `type.__call__()`# 3. inside has __new__() and __init__()# 4. python will look for __new__() in our cls# 5. if cant find, it uses type.__new__()# 6. by defining __new__(): we can add custom behaviour# 7. super().__new__(cls, name,bases, dcts) is the same# as type.__new__(...), or we are doing nothing new here# 8. then we add custom beaviour x._secret_attr = ... x._secret_attr ="gday mate"# 9. return object (as would default type.__new__())return xclass FooFoo(metaclass=TonyMetaClass):passfoofoo = FooFoo()
foofoo._secret_attr
'gday mate'
7. Simple Object Factory
class FooObjectFactory():def__init__(self):self.attr =777a = FooObjectFactory() b = FooObjectFactory() c = FooObjectFactory() print(a.attr, b.attr, c.attr) # each instance has initialised instance attr
777 777 777
8. Simple Class Factory
class MetaFooClsFactory(type):def__new__(cls, name, bases, dcts): # <metaclass> type.__new__() creates the class x =super().__new__(cls, name, bases, dcts) x._attr = ["888"] # x, the class itself, an instance type, has class._attrreturn x # return the x instance (the class)class AFooCls(metaclass = MetaFooClsFactory):passclass BFooCls(metaclass = MetaFooClsFactory):passclass CFooCls(metaclass = MetaFooClsFactory):passprint(AFooCls._attr, BFooCls._attr, CFooCls._attr) # each cls has initialised cls attr
['888'] ['888'] ['888']
9. Simple Inheritance
class Baz(): cls_attr ='999'class ABaz(Baz):passclass BBaz(Baz):passclass CBaz(Baz):passprint(ABaz.cls_attr, BBaz.cls_attr, CBaz.cls_attr)