认识metaclass

发布时间 2023-12-14 22:37:00作者: 有虫子啊

python的一切皆对象,没错类也是对象

>>> class Foo():
...     pass
...
>>>
>>> Foo.name = "Fo"

我们通过class关键字来定义一个类,我们也可以对这个类进行添加属性,添加方法等各种对象操作。

那么类是由谁创建的呢?

>>> class Foo():
...     pass
...
>>> type(Foo)
<class 'type'>

type可以用来动态创建类

>>> myclass = type("myClass",(), {"name":"obj"})
>>> myclass
<class '__main__.myClass'>
>>> obj = myclass()
>>> obj.name
'obj'

在python3中,我们可以显式的指定metaclass,如果未指定,那么就会默认使用type来创建

还记得python双下划线的私有方法么

比如

class Foo():
    def __foo__():
        pass

我们实例化 Foo().__foo__()会发生什么? 解释器会找不到该方法,实际方法名已经被修改成了 _Foo__foo__

怎么做到修改呢?正好metaclass可以实现这一特性

class UpperAttrMetaClass(type):

    def __new__(mcs, class_name, bases, attr):
        upper_attr = {
            item if item.startswith("__") else item.upper(): v for item, v in attr.items()
        }
        return type(class_name, bases, upper_attr)


class Foo(object, metaclass=UpperAttrMetaClass):

    def __init__(self):
        self.name = "Foo"

    def __protected_fun(self) -> str:
        return self.name


if __name__ == '__main__':
   print(dir(Foo))


>>>['_FOO__PROTECTED_FUN', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']

metaclass在实际场景的应用是啥?

很可惜,除了ORM这种复杂场景,我们基本使用不到

Metaclasses are deeper magic that 99% of users should never worry about it. 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).