• 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())
    

    image-20220131172823625

    传统方式更加的直观。

    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)
    

    image-20220131194436621

    改进:

    # -*- 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)
    

    image-20220131194644073

  • 相关阅读:
    网络唤醒的尝试
    远程桌面连接修改与远程连接的痕迹清理+User Profile Service服务未能登录,无法加载用户配置文件
    web与flash结合:不出现提示,直接关闭窗口(javascript)+直接关闭,不提示
    net framework 2.0,3.0与3.5三个版本之间关系
    c#连接access2003操作必须使用一个可更新的查询解决方法
    分析网络故障慢慢来!一定要抓到真凶(有关arp)
    GridView遭遇数据类型"是/否",获取gridview的一个单元格的值并更改,附带更新GridView用法
    查询和删除表中重复数据sql语句
    hibernate学习笔记
    不要在一门技术上吊死
  • 原文地址:https://www.cnblogs.com/Blogwj123/p/15858559.html
Copyright © 2020-2023  润新知