返回介绍

类的伪私有属性

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

除了较大的结构性目标,类设计往往也必须解决名称用法。在第五部分中,我们学到了每个在模块文件顶层赋值的变量名都会导出。在默认情况下,类也是这样:数据隐藏是一个惯例,客户端可以读取或修改任何它们想要的类或实例的属性。事实上,用C++术语来讲,属性都是"public"和"virtual",在任意地方都可进行读取,并且在运行时进行动态查找[1]

如今依然如此。然而,Python也支持变量名压缩(mangling,相当于扩张)的概念,让类内某些变量局部化。压缩后的变量名有时会被误认为是“私有属性”,但这其实只是一种把类所创建的变量名局部化的方式而已:名称压缩并无法阻止类外代码对它的读取。这种功能主要是为了避免实例内的命名空间的冲突,而不是限制变量名的读取。因此,压缩的变量名最好称为“伪私有”,而不是“私有”。

伪私有变量名是高级且完全可选的功能,除非你开始在多人的项目中编写大型的类的层次,否则可能不会觉得有什么用处。实际上,即便当它们可能应该使用的时候,也并非总是使用它们——更通俗地说,Python程序员用一个单个的下划线来编写内部名称(例如,_X),这只是一个非正式的惯例,让你知道这是一个不应该修改的名字(它对Python自身来说没有什么意义)。

由于你可能在其他人的代码中看见这个功能,所以即使不用,多少还是得留意。

变量名压缩概览

下面是变量名压缩的工作方式:class语句内开头有两个下划线,但结尾没有两个下划线的变量名,会自动扩张,从而包含了所在类的名称。例如,像Spam类内__X这样的变量名会自动变成_S pam__X:原始的变量名会在头部加入一个下划线,然后是所在类名称。因为修改后的变量名包含了所在类的名称,相当于变得独特。不会和同一层次中其他类所创建的类似变量名相冲突。

变量名压缩只发生在class语句内,而且只针对开头有两个下划线的变量名。然而,每个开头有两个下划线的变量名都会发生这件事,包括方法名称和实例属性名称(例如,在Spam类内,引用的self.__X实例属性会变成self._Spam__X)。因为不止有一个类在给一个实例新增属性,所以这种办法是有助于避免变量名冲突的。我们需要用一个例子来了解它是如何工作的。

[1]这会让使用C++的人产生不必要的恐慌。在Python中,甚至有可能在运行时修改或完全删除类的方法。另一方面,在实际的程序中,几乎没人会这样做。作为脚本语言,Python更关心的是开放而不是约束。此外,回想一下第29章讨论的运算符重载,__getattr__和__setattr__可用于模拟私有性,但是,实际中通常也很少使用。关于编写一个更加实际的私有性装饰器的更多讨论,参见本书第38章。

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

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

发布评论

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