| 
 | 
 
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册  
 
x
 
>>> # hasattr()用于判断对象中是否拥有某属性,getattr()用于获取对象中某属性的值,setattr()用于设置对象中某属性的值,delattr()用于删除对象中的某属性。与之相对应的有4个魔法方法,分别是__getattribute__()、__getattr__()、__setattr__()和__delattr__() 
>>> # 其中,__getattribute__()、__setattr__()和__delattr__()分别与getattr()、setattr()和delattr()相对应,而__getattr__()则是当用户试图获取一个不存在的属性时才会被触发的魔法方法,与getattr()貌合神离,不要搞错了。此外,无论访问的属性是否存在,__getattribute__()都会优先被触发;__setattr__()和__delattr__()看似普通不过的赋值或删除操作却可能会造成无限递归的“死亡螺旋”,只有使用super()或引入__dict__后再进行相应操作,曲线救国,方能安全实现。 
 
>>> # hasattr()用于判断对象中是否拥有某属性 
>>> class C: 
...         def __init__(self, name, age): 
...                 self.name = name 
...                 self.age = age 
...  
>>> c = C("小甲鱼", 18) 
>>> hasattr(c, "name") 
True 
 
>>> # getattr()用于获取对象中某属性的值 
>>> getattr(c, "name") 
'小甲鱼' 
>>> getattr(c, "age") 
18 
 
>>> # setattr()用于设置对象中某属性的值 
>>> setattr(c, "_C__age", 19) 
>>> getattr(c, "age") 
18 
>>> c.__dict__ 
{'name': '小甲鱼', 'age': 18, '_C__age': 19} 
>>> getattr(c, "_C__age") 
19 
 
>>> # delattr()用于删除对象中的某属性 
>>> delattr(c, "_C__age") 
>>> getattr(c, "_C__age") 
Traceback (most recent call last): 
  File "<stdin>", line 1, in <module> 
AttributeError: 'C' object has no attribute '_C__age' 
>>> c.__dict__ 
{'name': '小甲鱼', 'age': 18} 
 
>>> #__getattribute__():当获取属性时触发,对应getattr() 
>>> class C: 
...         def __init__(self, name, age): 
...                 self.name = name 
...                 self.__age = age 
...         def __getattribute__(self, item): 
...                 print("拿来吧你") 
...                 return super().__getattribute__(item) 
...  
>>> c = C('小甲鱼', 18) 
>>> print(getattr(c, 'name')) 
拿来吧你 
小甲鱼 
>>> print(c._C__age) 
拿来吧你 
18 
>>> try: 
...         c.Fishc 
... except AttributeError as e: 
...         print(e) 
...  
拿来吧你 
'C' object has no attribute 'Fishc' 
 
>>> #__getattr__():当试图获取一个不存在的属性时触发 
>>> class C: 
...         def __init__(self, name, age): 
...                 self.name = name 
...                 self.__age = age  
...         def __getattribute__(self, item): 
...                 print("拿来吧你") 
...                 return super().__getattribute__(item) 
...         def __getattr__(self, item): 
...                 if item == 'fishc': 
...                         print('I love fishc') 
...                 else: 
...                         raise AtttributeError(item) 
...  
>>> c = C('小甲鱼', 18) 
>>> try: 
...         c.x 
... except AttributeError as e: 
...         print(e) 
...  
拿来吧你 
Traceback (most recent call last): 
  File "<stdin>", line 2, in <module> 
  File "<stdin>", line 12, in __getattr__ 
NameError: name 'AtttributeError' is not defined 
 
>>> #__setattr__()当设置属性时触发,对应setattr() 
>>> # class D: 
>>> #     def __setattr__(self, name, value): 
>>> #         self.name = value 
>>> # 
>>> # d = D() 
>>> #  d.name = '小甲鱼'#报错RecursionError: maximum recursion depth exceeded 
>>> #捕获到赋值操作时,执行self.name = value,相当于又给自己调用了一次赋值操作,则会继续执行self.name = value,无限递归导致死循环 
>>> class D: 
...         def __setattr__(self, name, value): 
...                 self.__dict__[name] = value 
...  
>>> d = D() 
>>> d.name = '小甲鱼' 
>>> print(d.name) 
小甲鱼 
 
>>> #__delattr__():当一个属性被删除时触发,对应delattr() 
>>> class D: 
...         def __setattr__(self, name, value): 
...                 self.__dict__[name] = value 
...         def __delattr__(self, item): 
...                 del self.__dict__[item] 
...  
>>> d= D() 
>>> d.name = '小甲鱼' 
>>> print(d.__dict__) 
{'name': '小甲鱼'} 
>>> del d.name  
>>> print(d.__dict__) 
{} 
>>>  |   
 
 
 
 |