学习
实践
活动
工具
TVP
写文章

Python基础教程 再谈隐藏

7.2.4 再谈隐藏

默认情况下,可从外部访问对象的属性。再来看一下前面讨论封装时使用的示例。

>>> c.name

'Sir Lancelot'

>>> c.name = 'Sir Gumby'

>>> c.get_name()

'Sir Gumby'

有些程序员认为这没问题,但有些程序员(如Smalltalk①之父)认为这违反了封装原则。他们认为应该对外部完全隐藏对象的状态(即不能从外部访问它们)。你可能会问,为何他们的立场如此极端?由每个对象管理自己的属性还不够吗?为何要向外部隐藏属性?毕竟,如果能直接访问ClosedObject(对象c所属的类)的属性name,就不需要创建方法setName和getName了。

关键是其他程序员可能不知道(也不应知道)对象内部发生的情况。例如, ClosedObject可能在对象修改其名称时向管理员发送电子邮件。这种功能可能包含在方法set_name中。但如果直接设置c.name,结果将如何呢?什么都不会发生——根本不会发送电子邮件。为避免这类问题,可将属性定义为私有。私有属性不能从对象外部访问,而只能通过存取器方法(如get_name和

set_name)来访问。

注意 第9章将介绍特性(property),这是一种功能强大的存取器替代品。

Python没有为私有属性提供直接的支持,而是要求程序员知道在什么情况下从外部修改属性是安全的。毕竟,你必须在知道如何使用对象之后才能使用它。然而,通过玩点小花招,可获得类似于私有属性的效果。

要让方法或属性成为私有的(不能从外部访问),只需让其名称以两个下划线打头即可。

class Secretive:

def __inaccessible(self):

print("Bet you can't see me ...")

def accessible(self):

print("The secret message is:")

self.__inaccessible()

现在从外部不能访问__inaccessible,但在类中(如accessible中)依然可以使用它。

>>> s = Secretive()

>>> s.__inaccessible()

Traceback (most recent call last):

File "", line 1, in

AttributeError: Secretive instance has no attribute '__inaccessible'

>>> s.accessible()

The secret message is:

Bet you can't see me ...

虽然以两个下划线打头有点怪异,但这样的方法类似于其他语言中的标准私有方法。然而,幕后的处理手法并不标准:在类定义中,对所有以两个下划线打头的名称都进行转换,即在开头加上一个下划线和类名。

>>> Secretive._Secretive__inaccessible

只要知道这种幕后处理手法,就能从类外访问私有方法,然而不应这样做。

>>> s._Secretive__inaccessible()

Bet you can't see me ...

总之,你无法禁止别人访问对象的私有方法和属性,但这种名称修改方式发出了强烈的信号,让他们不要这样做。

如果你不希望名称被修改,又想发出不要从外部修改属性或方法的信号,可用一个下划线打头。这虽然只是一种约定,但也有些作用。例如, from module import *不会导入以一个下划线打头的名称。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20181025G0ELFS00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码关注腾讯云开发者

领取腾讯云代金券