返回介绍

属性引用:__getattr__ 和 __setattr__

发布于 2024-01-29 22:24:15 字数 1322 浏览 0 评论 0 收藏 0

__getattr__方法是拦截属性点号运算。更确切地说,当通过对未定义(不存在)属性名称和实例进行点号运算时,就会用属性名称作为字符串调用这个方法。如果Python可通过其继承树搜索流程找到这个属性,该方法就不会被调用。因为有这种情况,所以__getattr__可以作为钩子来通过通用的方式响应属性请求。例子如下:

在这里,empty类和其实例X本身并没有属性,所以对X.age的存取会转至__getattr__方法,self则赋值为实例(X),而attrname则赋值为未定义的属性名称字符串("age")。这个类传回一个实际值作为X.age点号表达式的结果(40),让age看起来像实际的属性。实际上,age变成了动态计算的属性。

对于类不知道该如何处理的属性,这个__getattr__会引发内置的AttributeError异常,告诉Python,那真的是未定义属性名。请求X.name时,会引发错误。当我们在后两章看到实际的委托和内容属性时,你会再看到__getattr__,而在第七部分会再介绍关于异常的更多细节。

有个相关的重载方法__setattr__会拦截所有属性的赋值语句。如果定义了这个方法,self.attr=value会变成self.__setattr__('attr',value)。这一点技巧性很高,因为在__setattr__中对任何self属性做赋值,都会再调用__setattr__,导致了无穷递归循环(最后就是堆栈溢出异常)。如果想使用这个方法,要确定是通过对属性字典做索引运算来赋值任何实例属性的(下一节讨论)。也就是说,是使用self.__dict__['name']=x,而不是self.name=x。

有两个属性访问重载方法,允许我们控制或特化对对象中的属性的访问。它们倾向于扮演高度专用的角色,其中的一些我们将在本书后面介绍。

其他属性管理工具

为了便于将来参考,还要注意,有其他的方式来管理Python中的属性访问:

·__getattribute__方法拦截所有的属性获取,而不只是那些未定义的,但是,当使用它的时候,必须比使用__getattr__更小心地避免循环。

·Property内置函数允许我们把方法和特定类属性上的获取和设置操作关联起来。

·描述符提供了一个协议,把一个类的__get__和__set__方法与对特定类属性的访问关联起来。

由于这些颇有些高级的工具并不是对每个Python程序员都有用,所以我们将推迟到本书第31章再介绍这些特性,并且在第37章再详细地介绍所有属性管理技术。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文