理解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
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值