python之__getattribute__方法 || __getattr__方法 || __setattr__方法 ||__delattr__方法 || __dir__方法
前言
python语言的五个魔术方法,他们都与Python属性相关,涉及获取、删除和修改。
__getattribute__方法
源码如下:
实战演练:
①首先定义一个类并访问类的对象属性:
class User: def __init__(self, name, sex): self.name = name self.sex = sex u1 = User(name='li', sex='male') print(u1.name)
运行结果:
②接着在该类中加入 __getattribute__ 魔方方法。【访问对象属性就会交给该魔方方法处理】
class User: def __getattribute__(self, item): return '无论对象是否存在该属性,都会返回此值' def __init__(self, name, sex): self.name = name self.sex = sex u1 = User(name='li', sex='male') print(u1.name) print(u1.age)
运行结果:【因为User类中的 __getattribute__ 魔方方法重写了基类object类的方法,所以此时的 __getattribute__ 方法不在返回对象的属性,而是返回程序中重写后的内容】
__getattribute__ 魔方方法介绍
①触发时间:在访问对象成员属性的时候触发,无论对象的成员属性是否存在。
②作用:对属性进行一些处理。
③参数:
- self为当前对象;
- item是访问属性名称的字符串。
④返回值:对象的属性值。
【注意】
① __getattribute__ 方法的是返回值千万不能用 self.name ,否则获取对象属性时会无限递归下去,
例如:
class User: def __getattribute__(self, item): return self.name def __init__(self, name, sex): self.name = name self.sex = sex u1 = User('li', 'male') print(u1.name)
运行结果:
②可以使用 object.__getattribute__ 方法来访问对象成员属性。
例如:
class User: def __getattribute__(self, item): return object.__getattribute__(self, item) def __init__(self, name, sex): self.name = name self.sex = sex u1 = User('li', 'male') print(u1.name)
运行结果:
__getattr__方法
- 触发时间:在访问不存在的对象属性的时候触发。
- 作用:访问不存在的属性时候,不会报错。
- 参数:self为当前对象,item是访问属性名称的字符串。
- 返回值:属性值。
我们举个简单例子,就是用户可能会输出属性名称,那我们都统一返回name属性。
class User: def __getattr__(self, item): return self.name def __init__(self, name, sex): self.name = name self.sex = sex u1 = User('li', 'male') print(u1.na2me) li
__setattr__方法
- 触发时间:添加和修改对象属性的时候触发。
- 作用:限制添加和修改对象属性的操作。
- 参数:self为当前对象,key为设置对象属性名称, value为设置的值。
- 返回值:无。
例如,我们让用户可以改name,不能改sex。
__delattr__方法
- 触发时间:删除对象属性的时候触发。
- 作用:限制添加和修改对象属性的操作。
- 参数:self为当前对象,item为删除对象属性名称。
- 返回值:无。
例如:我们可以让用户删除sex,但是不能删除name。
class User: def __delattr__(self, item): if item == 'sex': pass else: object.__delattr__(self, item) def __init__(self, name, sex): self.name = name self.sex = sex u1 = User('li', 'male') del u1.sex print(u1.sex) del u1.name print(u1.name) male AttributeError: 'User' object has no attribute 'name'
__dir__方法以及Python __dict__与dir()区别
Python下一切皆对象,每个对象都有多个属性(attribute),Python对属性有一套统一的管理方案。
__dir__方法详细查看此篇博客:https://www.cnblogs.com/hls-code/p/15262760.html
__dict__与dir()
的区别:
- dir()是一个函数,返回的是list;
__dict__
是一个字典,键为属性名,值为属性值;- dir()用来寻找一个对象的所有属性,包括
__dict__
中的属性,__dict__
是dir()的子集;
dir()是Python提供的一个API函数,dir()函数会自动寻找一个对象的所有属性(包括从父类中继承的属性)。
一个实例的__dict__
属性仅仅是那个实例的实例属性的集合,并不包含该实例的所有有效属性。所以如果想获取一个对象所有有效属性,应使用dir()。
print dir(A) ''' ['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'age', 'class_f', 'class_var', 'fun', 'level1', 'level2', 'name', 'num', 'static_f'] ''' a_dict = a.__dict__.keys() A_dict = A.__dict__.keys() object_dict = object.__dict__.keys() print a_dict print A_dict print object_dict ''' ['fun', 'level1', 'age', 'name'] ['__module__', 'level2', 'num', 'static_f', '__dict__', '__weakref__', '__init__', 'class_f', 'class_var', 'fun', '__doc__'] ['__setattr__', '__reduce_ex__', '__new__', '__reduce__', '__str__', '__format__', '__getattribute__', '__class__', '__delattr__', '__subclasshook__', '__repr__', '__hash__', '__sizeof__', '__doc__', '__init__'] ''' #因为每个类都有一个__doc__属性,所以需要去重,去重后然后比较 print set(dir(a)) == set(a_dict + A_dict + object_dict) #True
https://www.cnblogs.com/zjchao/p/7894477.html
属性访问顺序
最后,属性访问的顺序如下:
- __getattribute__
- 数据描述符
- 当前对象的属性
- 类的属性
- 非数据描述符
- 父类的属性
- __getattr__
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!