理解metaclass||metadata in Python

  • metaclass

    Metaclasses are an espteric OOP concept, lurking behind virtually all Python code.

    The use of custom metaclasses is somewhat controvesial, as suggested by the following quote from Tim Peters, the Python guru who authored the Zen of Python:

    Metaclasses are deeper magic than 99% of users should ever worry about. If you wonder whether you need them, you don’t (the people who actually need them know with certainty that they need them, and don’t need an explanation about why)

    Even most programmers rarely have to think about metaclasses, Still, understanding Python metaclasses is worthwhile, because it leads to a better understanding of the internals of Python classes in general. You never know: you may one day find yourself in one of those situations where you just know that a custom metaclass is what you want.

  • Old-style vs. New-Style Classes

    • old-style classes

      With old-style classes, class and type are not quite the same thing. An instance of an old-style class is always implemented from a single built-in type called instance.

      If obj is an instance of an old-style class, obj.__class__ designates the class, but type(obj) is always instance.

    • new-style classes

      New-style classes unify the concepts of class and type.

      If obj is an instance of a new-style class, type(obj) is the same as obj.__class__

  • Type and Class

    In Python3, all classes are new-style classes. Thus , in Python3 it is reasonable to refer to an object’s type and its class interchangeably.

    Everything in Python is an object, a class must have a type.

    >>> class Foo:
    ...     pass
    ...
    >>> x = Foo()
    
    >>> type(x)
    <class '__main__.Foo'>
    
    >>> type(Foo)
    <class 'type'>
    

    The type of x is class Foo, But the type of Foo is type always(like int, str, float, …).

    For the matter, the type of type is type as well.

    type is a metaclass, of which classes are instances. Just as an ordinary object is an instance of a class, any new-style class in Python, and thus any class in Python 3, is an instance of the type metaclass.

    In the above case:

    • x is an instance of class Foo
    • Foo is an instance of the type metaclass
    • type is also an instance of the type metaclass, so it is an instance of itself
  • Defining a Class Dynamically

    The built-in type() function, when passed one argument, returns the type of an object. For new-style classes, that is generally the same as the object’s __class__ attribute

    You can also call type() with three arguments – type(<name>, <bases>, <dct>):

    • <name> specifies the class name. This becomes the __name__ attribute of the class.
    • <bases> specifies a tuple of the base classes from which the class inherits. This becomes the __bases__ attribute of the class.
    • <dct> specifies a namespace dictionary containing definitions for the class body. This becomes the __dict__ attribute of the class.

    Calling type() in this manner creates a new instance of the type metaclass. In other words, it dynamically creates a new class.

  • Class initialization

    When the interpreter encounters a custom Class Foo, the following occurs:

    • The __call__() method of Foo's parent class is called. Which means the type metaclass, so type's __call__() method is invoked.
    • The __call__() method in turn invokes the following:
      1. __new__()
      2. __init__()

    If Foo does not define __new__() and __init__() , default methods are inherited from Foo's ancestry. But if Foo does define these methods, they override those from the ancestry, which allows for customized behavior when instantiating Foo.

    This modifies the instantiation behavior of class Foo: each time an instance of Foo is created, by default it is initialized with an attribute called attr, which has a value of 100.

    Code like this would more usually appear in the __inti__() method.

    You can’t change the type's __new__() since it’s metaclass. But you can make a custom metaclass which derives from type.

  • References

  1. Real Python : Python Metaclasses
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章