目录
前言:1、实例属性管理__dict__2、__setattr__()与__dict__3、重载__setattr__()必须谨慎总结:前言:
python提供了诸多的魔法方法,其中__setattr__()方法主要用于类实例进行属性赋值,其定义在Object类官方提供的说明如下:
Called when an attribute assignment is attempted.
This is called instead of the normal mechanism (i.e. store the value in the instance dictionary).
name is the attribute name, value is the value to be assigned to it.
简单的说,__setattr__()在属性赋值时被调用,并且将值存储到实例字典中,这个字典应该是self的__dict__属性。即:在类实例的每个属性进行赋值时,都会首先调用__setattr__()方法,并在__setattr__()方法中将属性名和属性值添加到类实例的__dict__属性中。
1、实例属性管理__dict__
下面的测试代码中定义了三个实例属性,每个实例属性注册后都print()
此时的__dict__
,
代码如下:
class AnotherFun: def __init__(self): self.name = "Liu" print(self.__dict__) self.age = 12 print(self.__dict__) self.male = True print(self.__dict__) another_fun = AnotherFun()
得到的结果显示出,每次实例属性赋值时,都会将属性名和对应值存储到__dict__字典中:
{"name": "Liu"} {"name": "Liu", "age": 12} {"name": "Liu", "age": 12, "male": True}
2、__setattr__()与__dict__
由于每次类实例进行属性赋值时都会调用__setattr__()
,所以可以重载__setattr__()方法,来动态的观察每次实例属性赋值时__dict__()的变化。下面的Fun类重载了__setattr__()方法,并且将实例的属性和属性值作为__dict__的键-值对:
class Fun: def __init__(self): self.name = "Liu" self.age = 12 self.male = True def __setattr__(self, key, value): print("*"*50) print("setting:{}, with:{}".format(key[], value)) print("current __dict__ : {}".format(self.__dict__)) # 属性注册 self.__dict__[key] = value fun = Fun()
通过在__setattr__()中将属性名作为key,并将属性值作为value,添加到了__dict__中,得到的结果如下:
**************************************************
setting:name, with:Liu
current __dict__ : {}
**************************************************
setting:age, with:12
current __dict__ : {"name": "Liu"}
**************************************************
setting:male, with:True
current __dict__ : {"name": "Liu", "age": 12}
可以看出,__init__()中三个属性赋值时,每次都会调用一次__setattr__()
函数。
3、重载__setattr__()必须谨慎
由于__setattr__()
负责在__dict__中对属性进行注册,所以自己在重载时必须进行属性注册过程,下面是__setattr__()不进行属性注册的例子:
class NotFun: def __init__(self): self.name = "Liu" self.age = 12 self.male = True def __setattr__(self, key, value): pass not_fun = NotFun() print(not_fun.name)
由于__setattr__中并没有将属性注册到__dict__中,所以not_fun对象并没有name属性,因此最后的print(not_fun.name)会报出属性不存在的错误:
AttributeError Traceback (most recent call last)
in ()
8 pass
9 not_fun = NotFun()
---> 10 print(not_fun.name)AttributeError: "NotFun" object has no attribute "name"
所以,重载__setattr__时必须要考虑是否在__dict__中进行属性注册。
总结:
python的实例属性的定义、获取和管理可以通过__setattr__()和__dict__配合进行,当然还有对应的__getattr__()方法,本文暂时不做分析。__setattr__()方法在类的属性赋值时被调用,并通常需要把属性名和属性值存储到self的__dict__字典中。
到此这篇关于python魔法方法之__setattr__()的文章就介绍到这了,更多相关python魔法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
X 关闭
X 关闭
- 15G资费不大降!三大运营商谁提供的5G网速最快?中国信通院给出答案
- 2联想拯救者Y70发布最新预告:售价2970元起 迄今最便宜的骁龙8+旗舰
- 3亚马逊开始大规模推广掌纹支付技术 顾客可使用“挥手付”结账
- 4现代和起亚上半年出口20万辆新能源汽车同比增长30.6%
- 5如何让居民5分钟使用到各种设施?沙特“线性城市”来了
- 6AMD实现连续8个季度的增长 季度营收首次突破60亿美元利润更是翻倍
- 7转转集团发布2022年二季度手机行情报告:二手市场“飘香”
- 8充电宝100Wh等于多少毫安?铁路旅客禁止、限制携带和托运物品目录
- 9好消息!京东与腾讯续签三年战略合作协议 加强技术创新与供应链服务
- 10名创优品拟通过香港IPO全球发售4100万股 全球发售所得款项有什么用处?