Python 元类

Posted 紫青宝剑

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python 元类相关的知识,希望对你有一定的参考价值。

Python 元类

  • 平时使用较少,模块、框架没必要用元类。

1.创建类

1.1 传统模式

class Foo:
    def __init__(self,a):
        self.a=a
    def __new__(cls, *args, **kwargs):
        data=object.__new__(cls)
        return data

obj1=Foo(\'啊哈哈\')
print(obj1)
print(obj1.a)

对象,是基于类来创建出来的

问题:类是由谁创建的?

Python中类默认由type创建。

1.2 非传统方式

# 非传统方式
Fa=type(\'Fa\',(object,),\'name\':\'啊哈哈\',\'func\':lambda self:123)
obj2=Fa()
print(obj2)
print(obj2.name)
print(obj2.func())

传统方式更加的直观。

2.元类

默认由 type 创建,怎么让一个类的创建改成其他的东西呢?元类。

元类,指定类由谁来创建。

# type 创建Foo类型
class Foo(object):
    pass
# `东西`创建Foo类型
class Foo(object,metaclass=`东西`):
    pass

补充:

class Fa:
    def __call__(self, *args, **kwargs):
        print("我执行了")
obj=Fa()
obj()

#对象名加括号调用__call__方法。
>>> 我执行了

元类创建类

class MyType(type):
    def __init__(self,*args,**kwargs):
        super().__init__(*args,**kwargs)

    def __new__(cls, *args, **kwargs):
        # 创建类
        new_cls=super().__new__(cls,*args,**kwargs)
        return new_cls

    def __call__(self, *args, **kwargs):
        # 1.调用自己类的 __new__ 方法创建对象
        empty_object=self.__new__(self)
        # 2.调用自己类的 __init__ 方法去初化
        self.__init__(empty_object,*args,**kwargs)

# 假设Foo是一个对象,由MyType创建。
# Foo类其实是MyType的一个对象。
# Foo()   -> MyType对象()


class Foo(object,metaclass=MyType):
    def __init__(self,name):
        self.name=name

obj=Foo("啊哈")
print(obj)
print(obj.name)

3.使用元类创建单利模式

# -*- coding: utf-8 -*-
\'\'\'
@Time    : 2022/1/31 19:34
@Author  : ziqingbaojian
@File    : 03.单利模式.py
\'\'\'

class MyType(type):
    def __init__(self,name,bases,attrs):
        super().__init__(name,bases,attrs)
        self.instance=None

    def __call__(self, *args, **kwargs):
        # 1.判断是否有对象,有,则不创建。没有,则创建。
        if not self.instance:
            self.instance=self.__new__(self)
        # 2.调用自己类的 __init__ 方法去初化
        self.__init__(self.instance,*args,**kwargs)
        return self.instance

class Foo(object,metaclass=MyType):
    pass

obj1=Foo()
obj2=Foo()
print(obj1)
print(obj2)

改进:

# -*- coding: utf-8 -*-
\'\'\'
@Time    : 2022/1/31 19:34
@Author  : ziqingbaojian
@File    : 03.单利模式.py
\'\'\'

class MyType(type):
    def __init__(self,name,bases,attrs):
        super().__init__(name,bases,attrs)
        self.instance=None

    def __call__(self, *args, **kwargs):
        # 1.判断是否有对象,有,则不创建。没有,则创建。
        if not self.instance:
            self.instance=self.__new__(self)
        # 2.调用自己类的 __init__ 方法去初化
        self.__init__(self.instance,*args,**kwargs)
        return self.instance

class Singleton(object,metaclass=MyType):
    pass

class Foo(Singleton):
    pass

obj1=Foo()
obj2=Foo()
print(obj1)
print(obj2)

以上是关于Python 元类的主要内容,如果未能解决你的问题,请参考以下文章

Python—元类

python 元类

Python之元类ORM

具有自定义元类行为的 Python 元类

Python-元类 单例

python 的元类