返回介绍

类、方法以及嵌套作用域

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

这个陷阱在Python 2.2引入嵌套函数作用域后就消失了,不过本书对此进行了保留,只是作为历史回顾,也是为旧版本Python的用户着想,因为这可以示范当一层嵌套是类时,新的嵌套函数作用域会发生什么事情。

类引入了本地作用域,就像函数一样。所以相同的作用域行为也会发生在class语句的主体中。此外,方法是嵌套函数,也有相同的问题。当类进行嵌套时,看起来令人困惑就比较常见了。

下面的例子中(文件nester.py),generate函数返回嵌套的Spam类的实例。在其代码中,类名称Spam是在generate函数的本地作用域中赋值的。但是,在Python 2.2以前,在类的方法函数中,是看不见类名称S pam的。方法只能读取其自己的本地作用域、generate所在的模块以及内置变量名。

这个例子可在Python 2.2和以后的版本中执行,因为任何所在函数def的本地作用域都会自动被嵌套的def中看见(包括嵌套的方法def,就像这个例子所演示的那样)。但是,Python 2.2之前的版本就行不通了(参考之后的可能解决方案)。

注意,即使是在2.2版中,方法def还是无法看见所在类的局部作用域。方法def只看得见所在def的局部作用域。这就是为什么方法得通过self实例,或类名称去引用所在类语句中定义的方法和其他属性。例如,方法中的程序代码必须使用self.count或Spam.count,不能只是count。

如果你正在使用2.2版以前的版本,有很多方式可以使用上一个例子。其中一种最简单的方式,就是以全局声明,把名称S pam放在所在模块的作用域中。因为方法看得见所在模块中的全局变量名,就能够引用Spam。

更好的替代做法是重构代码,使得Spam定义在模块顶层,而不是使用全局声明。嵌套方法函数和顶层generate就会在全局作用域中找到Spam。

事实上,这种做法适用于所有Python版本。一般而言,如果避免嵌套类和函数,代码都会比较简单。

如果想做得既复杂又难懂,也可以完全放弃在方法中引用Spam,而是改用特殊的__class__属性,来返回实例的类对象。

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

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

发布评论

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