#!/bin/env python
class MetaType(type):
def __new__(cls, name, bases, attrs):
print("in meta new")
print("name: " + name)
print("bases: " + str(bases))
print("attrs: " + str(attrs))
print("klas info: " + str(cls.__class__))
# return type(name, bases, attrs)
# Above code will lose metatype info,
# which De will be built by 'type', not this MetaType.
return type.__new__(cls, name, bases, attrs)
def __init__(cls, name, bases, attrs):
# cls is returned by this def __new__
print("in meta init")
print(dir(cls))
def __call__(cls, *args, **kwargs):
print("In meta call")
# will call type instance's __new__ and __init__
instance = type.__call__(cls, *args, **kwargs)
return instance
class Base(object):
__metaclass__ = MetaType
def __new__(cls):
print("in base new")
print(cls.__class__) # Print MetaType
return super(Base, cls).__new__(cls)
def __init__(self, opt):
print("Base init")
class De(Base):
def __new__(cls, input):
print("in De new")
print(cls.__class__) # Print MetaType
# return super(Base, cls).__new__(cls) # will bypass Base's __new__
return super(De, cls).__new__(cls)
def __init__(self, input):
print("De init")
def testFunc(self):
pass
if __name__ == "__main__":
"""
1. Constructing Base type instance.
2. Call MetaType __new__, must return with type.__new__, otherwise using
type(...) with lose the metaclass info.
3. Call MetaType __init__
4. Call MetaType __new__, must return with type.__new__, otherwise using
type(...) with lose the metaclass info.
This time with 'De's info.
5. Call MetaType __init__
6. Since we call De("hi"), now call MetaType's def __call__
inside it should call type.__call__ to trigger
calling MetaType's instance's(aka. De) __new__ and __init__
7. De's __new__ should call super in order to trigger base instance's
__new__
8. De's __init__ should call super in order to trigger base instance's
__init__
"""
a = De("hi")
-----------in meta new
name: Base
bases: (<type 'object'>,)
attrs: {'__module__': '__main__', '__metaclass__': <class '__main__.MetaType'>, '__new__': <function __new__ at 0x7fe775497c80>, '__init__': <function __init__ at 0x7fe775497cf8>}
klas info: <type 'type'>
in meta init
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__metaclass__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
in meta new
name: De
bases: (<class '__main__.Base'>,)
attrs: {'__module__': '__main__', 'testFunc': <function testFunc at 0x7fe775497e60>, '__new__': <function __new__ at 0x7fe775497d70>, '__init__': <function __init__ at 0x7fe775497de8>}
klas info: <type 'type'>
in meta init
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__metaclass__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'testFunc']
In meta call
in De new
<class '__main__.MetaType'>
in base new
<class '__main__.MetaType'>
De init
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.