首页 > Python资料 博客日记
python高级之元类
2024-03-10 00:00:05Python资料围观138次
一、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 666
print(A) #<class '__main__.A'>
2、非传统方式
类名
继承类
成员
A1 = type('A', (object,), {"v1": 123, "func": lambda self: 666})
print(A1) #<class '__main__.A'>
# 根据类创建对象
obj1 = A1() #<__main__.A object at 0x0000017049D035E0>
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
执行结果
new
<class '__main__.Foo'>
init
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()
执行结果
init
111
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、当我们不写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加括号
标签:
相关文章
最新发布
- 【Python】selenium安装+Microsoft Edge驱动器下载配置流程
- Python 中自动打开网页并点击[自动化脚本],Selenium
- Anaconda基础使用
- 【Python】成功解决 TypeError: ‘<‘ not supported between instances of ‘str’ and ‘int’
- manim边学边做--三维的点和线
- CPython是最常用的Python解释器之一,也是Python官方实现。它是用C语言编写的,旨在提供一个高效且易于使用的Python解释器。
- Anaconda安装配置Jupyter(2024最新版)
- Python中读取Excel最快的几种方法!
- Python某城市美食商家爬虫数据可视化分析和推荐查询系统毕业设计论文开题报告
- 如何使用 Python 批量检测和转换 JSONL 文件编码为 UTF-8
点击排行
- 版本匹配指南:Numpy版本和Python版本的对应关系
- 版本匹配指南:PyTorch版本、torchvision 版本和Python版本的对应关系
- Python 可视化 web 神器:streamlit、Gradio、dash、nicegui;低代码 Python Web 框架:PyWebIO
- 相关性分析——Pearson相关系数+热力图(附data和Python完整代码)
- Python与PyTorch的版本对应
- Anaconda版本和Python版本对应关系(持续更新...)
- Python pyinstaller打包exe最完整教程
- Could not build wheels for llama-cpp-python, which is required to install pyproject.toml-based proj