扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
本篇文章为大家展示了Python中的属性访问方式有哪些,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。
创新互联建站是一家集网站建设,平凉企业网站建设,平凉品牌网站建设,网站定制,平凉网站建设报价,网络营销,网络优化,平凉网站推广为一体的创新建站企业,帮助传统企业提升企业形象加强企业竞争力。可充分满足这一群体相比中小企业更为丰富、高端、多元的互联网需求。同时我们时刻保持专业、时尚、前沿,时刻以成就客户成长自我,坚持不断学习、思考、沉淀、净化自己,让我们为更多的企业打造出实用型网站。属性的访问机制
一般情况下,属性访问的默认行为是从对象的字典中获取,并当获取不到时会沿着一定的查找链进行查找。例如 a.x 的查找链就是,从 a.__dict__['x'] ,然后是 type(a).__dict__['x'] ,再通过 type(a) 的基类开始查找。
若查找链都获取不到属性,则抛出 AttributeError 异常。
__getattr__ 方法
__getattr__函数的作用: 如果属性查找(attribute lookup)在实例以及对应的类中(通过__dict__)失败, 那么会调用到类的__getattr__函数, 如果没有定义这个函数,那么抛出AttributeError异常。由此可见,__getattr__一定是作用于属性查找的最后一步,兜底。
这个方法是当对象的属性不存在是调用。如果通过正常的机制能找到对象属性的话,不会调用 __getattr__ 方法。
class A: a = 1 def __getattr__(self, item): print('__getattr__ call') return item t = A() print(t.a) print(t.b) # output 1 __getattr__ call b
__getattribute__ 方法
这个方法会被无条件调用。不管属性存不存在。如果类中还定义了 __getattr__ ,则不会调用 __getattr__() 方法,除非在 __getattribute__ 方法中显示调用 __getattr__() 或者抛出了 AttributeError 。
class A: a = 1 def __getattribute__(self, item): print('__getattribute__ call') raise AttributeError def __getattr__(self, item): print('__getattr__ call') return item t = A() print(t.a) print(t.b)
所以一般情况下,为了保留 __getattr__ 的作用, __getattribute__() 方法中一般返回父类的同名方法:
def __getattribute__(self, item): return object.__getattribute__(self, item)
使用基类的方法来获取属性能避免在方法中出现无限递归的情况。
__get__ 方法
这个方法比较简单说明,它与前面的关系不大。
如果一个类中定义了 __get__() , __set__() 或 __delete__() 中的任何方法。则这个类的对象称为描述符。
class Descri(object): def __get__(self, obj, type=None): print("call get") def __set__(self, obj, value): print("call set") class A(object): x = Descri() a = A() a.__dict__['x'] = 1 # 不会调用 __get__ a.x # 调用 __get__
如果查找的属性是在描述符对象中,则这个描述符会覆盖上文说的属性访问机制,体现在查找链的不同,而这个行文也会因为调用的不同而稍有不一样:
如果调用是对象实例(题目中的调用方式), a.x 则转换为调用: 。 type(a).__dict__['x'].__get__(a, type(a))
如果调用的是类属性, A.x 则转换为: A.__dict__['x'].__get__(None, A)
其他情况见文末参考资料的文档
__getitem__ 方法
这个调用也属于无条件调用,这点与 __getattribute__ 一致。区别在于 __getitem__ 让类实例允许 [] 运算,可以这样理解:
__getattribute__ 适用于所有 . 运算符;
__getitem__ 适用于所有 [] 运算符。
class A(object): a = 1 def __getitem__(self, item): print('__getitem__ call') return item t = A() print(t['a']) print(t['b'])
如果仅仅想要对象能够通过 [] 获取对象属性可以简单的:
def __getitem(self, item): return object.__getattribute__(self, item)
总结
当这几个方法同时出现可能就会扰乱你了。我在网上看到一份示例还不错,稍微改了下:
class C(object): a = 'abc' def __getattribute__(self, *args, **kwargs): print("__getattribute__() is called") return object.__getattribute__(self, *args, **kwargs) # return "haha" def __getattr__(self, name): print("__getattr__() is called ") return name + " from getattr" def __get__(self, instance, owner): print("__get__() is called", instance, owner) return self def __getitem__(self, item): print('__getitem__ call') return object.__getattribute__(self, item) def foo(self, x): print(x) class C2(object): d = C() if __name__ == '__main__': c = C() c2 = C2() print(c.a) print(c.zzzzzzzz) c2.d print(c2.d.a) print(c['a'])
上述内容就是Python中的属性访问方式有哪些,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注创新互联成都网站设计公司行业资讯频道。
另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流