一、定制属性访问
1.1 修改、新增属性: object.name=value
或 setattr(object:Any, name:str, value:Any)
属性存在就修改, 否则增加. 会触发 __setattr__
方法
class Cat:
name = "花花"
sex = "female"
age = "2years"
def __setattr__(self, key, value): # 当属性被修改或增加属性时触发此方法
print("修改属性")
self.__dict__[key] = value
cat = Cat()
setattr(cat, "name", "小花")
print(cat.name)
cat.age = "3years"
print(cat.age)
1.2 查询: object.attr
或 getattr(object:Any, name: str)
查询属性, 如果存在就返回属性值, 不存在则报错. 会触发 __getattribute__
方法
class Cat:
name = "花花"
sex = "female"
age = "2years"
def __getattribute__(self, item): # 查询属性时触发方法
print(f"查询属性: {item}")
return object.__getattribute__(self, item)
cat = Cat()
print(cat.age)
print(getattr(cat, "age"))
1.3 删除del object.name
或 delattr(object:Any, name:str)
从对象内存空间中删除属性name
, 触发 __delattr__
方法
class Cat:
name = "花花"
sex = "female"
age = "2years"
def __delattr__(self, item): # 删除属性时触发次方法.
print(f"删除属性: {item}")
cat = Cat()
delattr(cat, "name")
1.4 查询属性是否存在hasattr(object:Any, name: Any)
会去查询对象的属性,如果不存在发生触发异常,则返回False
,否则返回True
查询方式: 调用 __getattribute__
方法, 如果报错, 这属性不存在, 返回False
. 如果不报错, 属性存在, 返回True
class Cat:
name = "花花"
sex = "female"
age = "2years"
def __getattribute__(self, item):
print(f"查询属性: {item}")
return object.__getattribute__(self, item)
cat = Cat()
print(hasattr(cat, "nae")) # hasttr更具 __getattribute__ 是否出现异常来判断属性是否存在
补充
__getattr__
方法: 查询属性不存在时, 触发此方法
class Cat:
name = "花花"
sex = "female"
age = "2years"
def __getattribute__(self, item):
print(f"查询属性: {item}")
return object.__getattribute__(self, item)
def __getattr__(self, item):
print(f"查询属性: {item}, 不存在")
cat = Cat()
print(hasattr(cat, "nae"))
二、描述符
当一个类的属性是另一个类的实例时,我们称这个属性为描述符。
如果通过当前类实例查看,修改,删除这个属性,会触发另一个类的__get__
,__set__
,__delete__
方法
class Cls1:
def __get__(self, instance, owner):
print('获取')
def __set__(self, instance, value):
print('设置')
def __delete__(self, instance):
print('删除')
class Cls2:
ins = Cls1() # 描述符
# 当类的属性是另一个类的实例时,此属性成为描述符
cls2 = Cls2()
# cls2.ins # 会触发类Cls1的 __get__ 方法
# cls2.ins = 1 # 会触发Cls1的 __set__ 方法
# del cls2.ins # 会触发Cls1的 __delete__ 方法