Python中__dict__与实例属性触发__getattribute__的差异及疑问
Python属性访问与赋值的实验分析
实验验证与现象
1. 验证self.__dict__会触发__getattribute__
class Room: def __init__(self,name): self.name = name def __getattribute__(self,attr): print('in __getattribute__',attr) return object.__getattribute__(self,attr) def __setattr__(self,attr,value): print('in __setattr__',attr) self.__dict__[attr] = value print('over')
实例化输出(含注释):
x = Room('r1') # __init__中的self.name = name触发__setattr__ in __setattr__ name # Python解释器解析self.__dict__[attr] = value时,提取self.__dict__触发__getattribute__ in __getattribute__ __dict__ over
可见解释器在解析代码片段时,部分操作会触发__getattribute__。
2. 描述符调用的特殊现象
class Sample: def __init__(self, name): self.name = name def __get__(self,instance,owner): print('get called') def __set__(self, instance, value): print('set called') class Person: name = Sample('name')
执行p = Person(); p.name会触发__get__方法,但执行p.name = 'tom'时仅触发__set__方法,疑问:为何赋值操作不先提取p.name触发__get__再执行赋值?
3. 反驳“默认__setattr__通过原生内部槽操作,不经过__getattribute__”的观点
针对该观点设计实验如下:
import time class Room: def __init__(self,name): self.name = name def __getattribute__(self,attr): print('in __getattribute__',attr) return object.__getattribute__(self,attr) def __setattr__(self,attr,value): print('in __setattr__',attr) time.sleep(3) self.__setattr__(attr, value) print('over')
实例化时会触发无限递归,由此可见self.__setattr__会触发__getattribute__。
初步结论
- 不触发
__getattribute__的表达式:
super().__setattr__(attr, value) object.__setattr__(self,attr, value)
- 触发
__getattribute__的表达式:
self.__setattr__(attr, value) self.__dict__[attr] = value
待解谜题
- 为何结构相似的三个表达式中,仅
self.__setattr__(attr, value)会触发__getattribute__? - 同为赋值语句,
self.__dict__[attr] = value会触发__getattribute__,为何self.name = name不会? - 在property中,
self.__setattr__('name', value)为何触发set方法而非__getattribute__?实验代码如下:
import time class Room: def __init__(self,value): self.name = value def get_name(self): print('in get') return self.__dict__['name'] def set_name(self, value): print('in set') time.sleep(3) self.__setattr__('name', value) name = property(get_name, set_name) r = Room('r1')
内容的提问来源于stack exchange,提问作者showkey
相关产品推荐
相关产品推荐

