Python类及元类的创建流程

ops/2024/11/13 10:02:51/

Python类及元类的创建流程

  • 代码
  • 运行结果
  • 再看type和object的关系和约定
  • type和object具有的方法不一样
  • 看代码和运行结果,可以完全理解python的执行过程。再补充几点,

代码

python">class MetaCls(type):print('0>>>', 'MetaCls', 0)def __init__(self, name, bases=None, dict=None):print('5>>>',self, '__init__',1)print('     MetaCls','__init__',id(self))super(MetaCls,self).__init__(name, bases, dict)def __new__(cls, *args, **kwagrs):print('4>>',cls, '__new__',2)print('     args',*args)print('     kwagrs',**kwagrs)print('     MetaCls','__new__',id(cls))print('     MetaCls','__mro__', MetaCls.__mro__)return super(MetaCls, cls).__new__(cls, *args, **kwagrs)print('1>>>', 'MetaCls',3)        print("========1========")class Pa(metaclass=MetaCls):print('2>>>', 'Pa',4)def __init__(self, num):self.num = numprint('7>>>', self, '__init__',5)print('     Pa','__init__',id(self))def __new__(cls, *args, **kwagrs):print('6>>>', cls, '__new__',6)print('     args',*args)print('     kwagrs',**kwagrs)print('     Pa','__new__',id(cls))print('     Pa','__mro__',Pa.__mro__)return super(Pa, cls).__new__(cls)# return object.__new__(cls)print('3>>>', 'Pa',7)print("========2========")son = Pa(10000)
print('8>>>',8)
print('     ',type(son))
print('9>>>',9)
print('     ',son.num)
print('     son',id(son))
print('10>>>',10)
metaclass = MetaCls('meta',(),{})
print('     metaclass', metaclass)

运行结果

python">0>>> MetaCls 0
1>>> MetaCls 3
========1========
2>>> Pa 4
3>>> Pa 7
4>> <class '__main__.MetaCls'> __new__ 2args Pa () {'__module__': '__main__', '__qualname__': 'Pa', '__init__': <function Pa.__init__ at 0xf62558>, '__new__': <function Pa.__new__ at 0xb9d520>, '__classcell__': <cell at 0xe00998: empty>}kwagrsMetaCls __new__ 12179720MetaCls __mro__ (<class '__main__.MetaCls'>, <class 'type'>, <class 'object'>)
5>>> <class '__main__.Pa'> __init__ 1MetaCls __init__ 16757312
========2========
6>>> <class '__main__.Pa'> __new__ 6args 10000kwagrsPa __new__ 16757312Pa __mro__ (<class '__main__.Pa'>, <class 'object'>)
7>>> <__main__.Pa object at 0x926870> __init__ 5Pa __init__ 9594992
8>>> 8<class '__main__.Pa'>
9>>> 910000son 9594992
10>>> 10
4>> <class '__main__.MetaCls'> __new__ 2args meta () {}kwagrsMetaCls __new__ 12179720MetaCls __mro__ (<class '__main__.MetaCls'>, <class 'type'>, <class 'object'>)
5>>> <class '__main__.meta'> __init__ 1MetaCls __init__ 11834720metaclass <class '__main__.meta'>

再看type和object的关系和约定

>>> object.__bases__
()>>> object.__bases__.__bases__
Traceback (most recent call last):File "<stdin>", line 1, in <module>
AttributeError: 'tuple' object has no attribute '__bases__'>>> object.__bases__.__class__
<class 'tuple'>>>> object.__class__
<class 'type'>>>> type.__bases__
(<class 'object'>,)>>> type.__class__
<class 'type'>>>> ().__bases__
Traceback (most recent call last):File "<stdin>", line 1, in <module>
AttributeError: 'tuple' object has no attribute '__bases__'>>> ().__class__
<class 'tuple'>>>> ().__class__.__bases__
(<class 'object'>,)

<a class=python中type和object的关系图" />

type和object具有的方法不一样

>>> dir(type)
['__abstractmethods__', '__annotations__', '__base__', '__bases__', '__basicsize__', '__call__', '__class__', '__delattr__', '__dict__', '__dictoffset__', '__dir__', '__doc__', '__eq__', '__flags__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__instancecheck__', '__itemsize__', '__le__', '__lt__', '__module__', '__mro__', '__name__', '__ne__', '__new__', '__or__', '__prepare__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__ror__', '__setattr__', '__sizeof__', '__str__', '__subclasscheck__', '__subclasses__', '__subclasshook__', '__text_signature__', '__weakrefoffset__', 'mro']>>> dir(object)
['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']

python_137">看代码和运行结果,可以完全理解python的执行过程。再补充几点,

  • __new__不一定需要重写。
  • 元类可以继承于object或者type或者其他类。如果没有显式的写成父类,默认是继承于object。
  • 如果元类要调用父类的__new__和__init__,传递的参数要和父类方法的一致。注意:type和object中的方法和参数是不一定相同,比如__new__的参数。官方文档对object的说明,官方文档对type的说明
  • object没有__call__。
  • __new__中一定有return返回类或实例,__init__中没有return。
  • 推荐阅读,其中核心之一是

class Foo(object, metaclass=MyMetaclass, kwarg1=value1):

它在元类中转换为
def new(cls, clsname, bases, dct, kwargs1=default):


http://www.ppmy.cn/ops/113670.html

相关文章

Langchain-chatchat源码部署及测试实验

一年多前接触到Langchain-chatchat的0.2版本,对0.2版本进行了本地部署和大量更新,但0.2版本对最新的大模型支持不够好,部署框架支持也不好且不太稳定,特别是多模态大模型,因此本次主要介绍0.3版本的源码部署,希望对大家有所帮助。Langchain-chatchat从0.3版本开始,支持更…

射击靶标检测系统源码分享

射击靶标检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vis…

主流卷积神经网络CNN总结

ResNet&#xff08;2015&#xff09;残差神经网络 残差结构 ResNet50具体卷积结构图 ResNeXt&#xff08;2016&#xff09;加入了分组卷积的思想&#xff0c;将原ResNet网络中的block替换成由group分组的block&#xff0c;两者得到的feature map一致&#xff0c;只是参数量更少…

【数据结构】排序算法---基数排序

文章目录 1. 定义2. 算法步骤2.1 MSD基数排序2.2 LSD基数排序 3. LSD 基数排序动图演示4. 性质5. 算法分析6. 代码实现C语言PythonJavaCGo 结语 ⚠本节要介绍的不是计数排序 1. 定义 基数排序&#xff08;英语&#xff1a;Radix sort&#xff09;是一种非比较型的排序算法&…

如何在安卓設備上更換IP地址?

IP地址是設備在網路中的唯一標識&#xff0c;通過IP地址&#xff0c;網路能夠識別並與設備進行通信。本文將詳細介紹在安卓設備上更換IP地址的幾種方法。 在安卓設備上更換IP地址的方法 1. 使用Wi-Fi網路更換IP地址 最簡單的方法是通過Wi-Fi網路更換IP地址。步驟如下&#x…

【Gateway】Gateway Filter Factories

Predicate决定了请求由哪一个路由处理,如果在请求处理前后需要加一些逻辑,这就是Filter(过滤器)的作用范围了.Filter分为两种类型:Pre类型和Post类型 滤器的两种类型 Pre 类型过滤器: 执行时机: 在请求被转发到后端服务之前执行。作用: 可以用来执行鉴权、限流、请求日志记录、…

【C++指南】inline内联函数详解

&#x1f493; 博客主页&#xff1a;倔强的石头的CSDN主页 &#x1f4dd;Gitee主页&#xff1a;倔强的石头的gitee主页 ⏩ 文章专栏&#xff1a;《C指南》 期待您的关注 目录 引言 C为什么引入了inline来替代C语言中的宏 inline的基本用法 定义inline函数 inline的优势与…

【ARM】A64指令介绍及内存屏障和寄存器

A64指令集介绍 ISA : Instruction System Architecture 指令集总结 跳转指令 使用跳转指令直接跳转&#xff0c;跳转指令有跳转指令B&#xff0c;带链接的跳转指令BL &#xff0c;带状态切换的跳转指令BX。 B 跳转指令&#xff0c;跳转到指定的地址执行程序。 BL 带链接的跳…