小工具知识网

当前位置: 首页 > 行业知识 > python高级之元类

行业知识

python高级之元类

2026-11-07 10:13:52 来源:互联网转载

python高级之元类

  • 一、Type创建类
    • 1、传统方式创建类
    • 2、非传统方式
    • 二、元类
    • 三、index.php/tags-41973.html" >���结

      一、Type创建类

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

      根据类创建对象

      obj=A(‘kobe’)

      1、执行类的new方法,创建对象(空对象),【构造方法】 {}

      2、执行类的init方法,初始化对象 ,【初始化方法】 {‘name’:‘kobe’}

      对象是基于类创建出来的;问题:类是由谁创建的?

      类默认是由type创建的

      1、传统方式创建类

      class A(object):    v1 = 123    def func(self):        return 666print(A)#

      2、非传统方式

      类名

      继承类

      成员

      A1 = type('A', (object,), {"v1": 123, "func": lambda self: 666})print(A1)        ## 根据类创建对象obj1 = A1()#print(obj1)# 调用对象中的func方法 print(obj1.func())  #666

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

      二、元类

      元类:指定类由谁来创建

      1、Foo类由MyType创建,代码如下

      class MyType(type):    pass# Foo类由MyType创建class Foo(object, metaclass=MyType):    pass

      2、假设Foo是一个对象,它是由MyType类创建。

      class MyType(type):    def __init__(self, *args, **kwargs):        print('init')        super().__init__(*args, **kwargs)    def __new__(cls, *args, **kwargs):        # 创建类        print('new')        new_cls = super().__new__(cls, *args, **kwargs)        print(new_cls)        return new_cls# 假设Foo是一个对象,由MyType类创建。class Foo(object, metaclass=MyType):    pass

      执行结果

      newinit

      3、类加括号得到的是对象,执行的是__init__()和__new__()方法,对象加括号执行__call__()方法

      class F1(object):    def __init__(self):        print('init')    # def __new__(cls, *args, **kwargs):    #     print('new')    def __call__(self, *args, **kwargs):        print(111)# 类加括号得到的是对象,执行的是__init__和__new__方法obj = F1()# 对象加括号执行call方法obj()

      执行结果

      init111

      4、假设Foo是一个对象,由MyType创建。

      Foo类其实是MyType的一个对象。

      Foo() 加括号执行的是——》MyType类中的__call__()方法

      __call__()方法实现的功能是:

      1、调用自己那个类的__new__方法创建对象

      empty_object=self.__new__(self)

      2、调用你自己那个类__init__方法去初始化对象

      self.__init__(empty_object,*args,**kwargs)

      3、将创建的对象返回:return empty_object

      class MyType(type):    def __init__(self, *args, **kwargs):        print('init')        super().__init__(*args, **kwargs)    def __new__(cls, *args, **kwargs):        # 创建类        print('new')        new_cls = super().__new__(cls, *args, **kwargs)        print(new_cls)        return new_cls    def __call__(self, *args, **kwargs):        # 1、调用自己哪个类的__new__方法创建对象        empty_object=self.__new__(self)        #2、调用你自己那个类 __init__方法去初始化        self.__init__(empty_object,*args,**kwargs)        return empty_object# 假设Foo是一个对象,由MyType创建。#  Foo类其实是MyType的一个对象。# Foo()  ——》MyType对象()class Foo(object, metaclass=MyType):    def __init__(self,name):        self.name=namev1=Foo('666')print(v1)print(v1.name)

      三、总结

      1、当我们不写MyType类时,Type中已经帮我们定义好了

      __init__

      __new__

      __call__ 方法了

      当我定义了MyType类时,

      __init__

      __new__

      __call__ 方法是我们自己定义的

      2、这就是为什么实例化对象的时候,先去创建对象再去初始化对象,Type类中已经实现了先 __new__()再__init__()

      3、代码从上到下执行,当执行到class Foo(object, metaclass=MyType)时

      先创建这个类,去MyType中的__new__()创建方法

      __init__()实例化方法,类在内存中创建好了,

      但是MyType中的__call__()方法是不执行的,因为类后面没有加括号

      如果类后面加了括号Foo(),会执行MyType的__call__()方法

      4、如果自己定义的类中实现了__call__方法,此时是不会执行的,因为Foo是MyType创建出来的

      5、如果要执行Foo类的__call__方法,需要实例化Foo类的对象v1,

      然后v1加括号


上一篇:数字身高怎么写?

下一篇:方舟服务器怎么才能玩?