您现在的位置是:首页 > 技术教程 正文

python高级之元类

admin 阅读: 2024-03-25
后台-插件-广告管理-内容页头部广告(手机)

在这里插入图片描述


python高级之元类

  • 一、Type创建类
    • 1、传统方式创建类
    • 2、非传统方式
  • 二、元类
  • 三、总结

一、Type创建类

class A(object): def __init__(self, name): self.name = name def __new__(cls, *args, **kwargs): data = object.__new__(cls) return data
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

根据类创建对象
obj=A(‘kobe’)
1、执行类的new方法,创建对象(空对象),【构造方法】 {}
2、执行类的init方法,初始化对象 ,【初始化方法】 {‘name’:‘kobe’}

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

1、传统方式创建类

class A(object): v1 = 123 def func(self): return 666 print(A) #
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

2、非传统方式

类名
继承类
成员

A1 = type('A', (object,), {"v1": 123, "func": lambda self: 666}) print(A1) # # 根据类创建对象 obj1 = A1() #<__main__.A object at 0x0000017049D035E0> print(obj1) # 调用对象中的func方法 print(obj1.func()) #666
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

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

二、元类

元类:指定类由谁来创建

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

class MyType(type): pass # Foo类由MyType创建 class Foo(object, metaclass=MyType): pass
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

执行结果

new <class '__main__.Foo'> init
  • 1
  • 2
  • 3

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()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

执行结果

init 111
  • 1
  • 2

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=name v1=Foo('666') print(v1) print(v1.name)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

三、总结

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加括号
在这里插入图片描述


在这里插入图片描述

标签:
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

在线投稿:投稿 站长QQ:1888636

后台-插件-广告管理-内容页尾部广告(手机)
关注我们

扫一扫关注我们,了解最新精彩内容

搜索
排行榜