python元类编程的基本使用

发布时间:2026/9/29 15:08:48
python元类编程的基本使用 元类编程的基本使用更新时间是在2023年02月22日, 具体的时刻是08:27:54, 作者是代码输入中...。这篇文章主要是讲了一下元类编程是怎么用的, 里面的示例代码写得特别具体, 对大家的学东西或者是干活儿都有点参考价值, 有需要的家伙们接下来就跟着小编一块来学一学吧。1.1.动态属性在面向对象编程里面, 通常情况下, 我们把那些名词性质的东西映射成属性, 把那些动词性质的东西映射成方法。在他们两个对应的情况下, 分别就是self.xxx这种形式的属性以及类方法这样的情况存在。但是, 有时候我们真正所需要的这些属性, 是需要根据其他的现有属性来进行动态计算才行的一种状态, 如果在这种情况下我们依然直接使用那种常规的属性方式来进行处理的话, 那么就很可能会引发数据不同步这样一个问题的发生。所以下面部分的内容, 我们就专门来重点介绍一下如何用这一个特定的符号标记的方法来实现对于动态类型的类属性的一个创建过程的相关操作环节。from datetime import datetime,dateclass User:def __init__(self,name,birthday):self.name nameself.birthday birthdayself._age 0propertydef age(self):return datetime.now().year - self.birthday.yearage.setterdef age(self,value):self._age valueif __name__ __main__:user User(derek,date(year1994,month11,day11))user.age 23print(user._age) # 23print(user.age) # 24 ,动态计算出来的1.2.和的区别.(self, name)当出现找不到的时候, 会执行调用的操作, 这一操作的结果会是返回一个具体的值或者是引发一种特定的异常。.(self, name)它是会被无条件地调用的, 并且是通过实例来访问其中的属性的。如果在这个类里面定义了某种特定的方法, 那么该方法就不会被进行调用, 但是这种情况需要排除掉显示出进行的调用, 或者是由于引发了异常所导致的情形。1调用一个不存在的属性class User:def __init__(self,info{}):self.info info# def __getattr__(self, item):# return self.info[item]if __name__ __main__:user User(info{name:derek,age:24})print(user.name)会报错2在把相应的东西添加上去了之后, 接着就可以直接开始进行调用了。class User:def __init__(self,info{}):self.info info#__getattr__是在查找不到属性的时候调用def __getattr__(self, item):return self.info[item]if __name__ __main__:user User(info{name:derek,age:24})print(user.name) #derek3class User:def __init__(self,info{}):self.info info#__getattr__是在查找不到属性的时候调用def __getattr__(self, item):return self.info[item]#__getattribute不管属性存不存在都访问这个def __getattribute__(self, item):return zhang_derekif __name__ __main__:user User(info{name:derek,age:24})#不管属性存不存在都走__getattribute__print(user.name) #zhang_derek #即使属性存在也走__getattribute__print(user.test) #zhang_derek #不存在的属性也能打印print(user.company) #zhang_derek #不存在的属性也能打印1.属性描述符是指用于定义对象属性特征的描述性结构。在验证赋值的时候, 需要去确认一下当前的值是不是整数类型。#属性描述符import numbers#只要一个类实现了下面三种魔法函数中的一种这个类就是属性描述符class IntField:def __get__(self, instance, owner):return self.valuedef __set__(self, instance, value):if not isinstance(value,numbers.Integral):raise ValueError(必须为int)self.value valuedef __delete__(self, instance):passclass User:age IntField()if __name__ __main__:user User()user.age 24print(user.age)假设变量里面的年龄数值等于二十四, 这个数据的类型是整数形式, 那么在进行显示输出的时候, 不会出现任何阻碍。如果给user.age传递字符串test, 也就是设置test这个参数的时候, 系统就会产生报错。1.4.和的区别1假如方法是没有任何东西返回的, 那么init方法就不会被执行。class User:def __new__(cls, *args, **kwargs):print(in new)def __init__(self,name):print(in init)self.name name# new是用用来控制对象的生成过程在对象生成之前# init是用来完善对象的# 如果new方法不返回对象则不会调用init函数if __name__ __main__:user User(derek)运行结果没有调用init方法2当对象被返回的时候, 就会执行初始化方法。class User:def __new__(cls, *args, **kwargs):print(in new) #in newprint(cls) #cls是当前class对象print(type(cls)) #return super().__new__(cls) #必须返回class对象才会调用__init__方法def __init__(self,name):print(in init) #in initprint(self) #self是class的实例对象 __main__.User object at 0x00000000021B8780print(type(self)) #self.name name# new是用用来控制对象的生成过程在对象生成之前# init是用来完善对象的# 如果new方法不返回对象则不会调用init函数if __name__ __main__:user User(namederek)#总结# __new__ 用来创建实例在返回的实例上执行__init__如果不返回实例那么__init__将不会执行# __init__ 用来初始化实例设置属性什么的1.5.自定义元类1在前面的准备工作环节中, 通过传入不同的字符串这个操作方法, 来达到动态地创建出不同类别的类的这样一个目的。def create_class(name):if name user:class User:def __str__(self):return userreturn Userelif name company:class Company:def __str__(self):return companyreturn Companyif __name__ __main__:Myclass create_class(user)my_obj Myclass()print(my_obj) #userprint(type(my_obj)) #.User2用type创建尽管前面说到的方式是可以进行创建的, 但是实际操作起来非常地繁琐且复杂。紧接着下面会给出使用 type 来创建类的简单实例。# 一个简单type创建类的例子#type(object_or_name, bases, dict)#type里面有三个参数第一个类名第二个基类名第三个是属性User type(User,(),{name:derek})my_obj User()print(my_obj.name) #derek3不但可以进行属性的定义工作, 而且还能够实现对方法的界定设定。def say(self): #必须加selfreturn i am derekUser type(User,(),{name:derek,say:say})my_obj User()print(my_obj.name) #derekprint(my_obj.say()) #i am derek4通过使用 type 这种方式去创建一个新的类, 然后让这个新创建的类去继承于那一个已经存在的基类。def say(self): #必须加selfreturn i am derekclass BaseClass:def answer(self):return i am baseclass#type里面有三个参数第一个类名第二个基类名第三个是属性User type(User,(BaseClass,),{name:derek,say:say})if __name__ __main__:my_obj User()print(my_obj.name) # derekprint(my_obj.say()) # i am derekprint(my_obj.answer()) # i am baseclass1.6. 什么是元类?所谓元类, 说白了它就是专门用来创建类的一个工具, 就像我们在上文那里所举的那个例子中的type那样。在实质的编码操作进程之中, 我们通常并不直接运用type参数去进行类的创建活动, 而是应当采用元类设计的书写策略方式,通过自行定制一款特定的元类对象来完成这一创建任务。# 把User类创建的过程委托给元类去做这样代码的分离性比较好class MetaClass(type):def __new__(cls, *args, **kwargs):return super().__new__(cls,*args, **kwargs)class User(metaclassMetaClass):def __init__(self,name):self.name namedef __str__(self):return testif __name__ __main__:#python中类的实例化过程会首先寻找metaclass通过metaclass去创建User类my_obj User(namederek)print(my_obj) #test这篇关于元类编程的文章介绍到这里就结束了, 对于更多相关元类编程的内容, 请大家去搜索脚本之家以前的文章, 或者继续浏览下面的相关文章, 希望大家能够以后多多支持脚本之家。