使用变量和方法的下划线与双下划线

有人很友好地向我解释了 _ _ method ()的错误,但是没有进一步打扰他,因为还有很多其他人需要帮助,我想知道是否有人可以进一步阐述这些差异。

例如,我不需要破坏,但是 _ 保持为私有,所以有人不能执行 instance e _ method () ?或者它只是通过使变量唯一来防止它覆盖另一个变量?我不需要我的内部方法“隐藏”,但因为他们是特定的使用,我不希望他们被用于类之外。

102016 次浏览

单个前导下划线只是一种约定,意思是“您可能不应该使用这个”它不会阻止某人使用该属性。

双前导下划线实际上更改了属性的名称,以便继承层次结构中的两个类可以使用相同的属性名称,而且它们不会发生冲突。

Python 中没有访问控制。您可以访问类的所有属性,其中包括错误的名称(如 _class__variable)。把注意力集中在代码和 API 上,而不是试图保护开发人员免受自己的伤害。

来自 PEP 8:

  • _single_leading_underscore: “内部使用”指示器弱。

    from M import *

    不导入名称以下划线开头的对象。

  • single_trailing_underscore_: 按照约定使用,以避免与 Python 关键字发生冲突,例如。

    Tkinter.Toplevel(master, class_='ClassName')

  • __double_leading_underscore: 在命名 class 属性时,调用 name 破坏(在 FooBar类内,__boo变成 _FooBar__boo; 见下文)

  • “魔法”物体或者 存在于用户控制的名称空间中的属性,例如 __init__, 不要发明这样的名字,只能使用它们 记录在案。

此外,从大卫 · 古杰的 代码就像 Python 主义者:

属性: interface_internal__private

但是尽量避免使用 __private表格。我从来不用它。相信我。如果你 使用它,你以后会后悔的。

说明:

来自 C + +/Java 背景的人特别容易 过度使用/滥用这个“特性”。但是 __private名称不工作的 就像 Java 或者 C + + 一样,他们只是触发了一个名字 目的是防止子类中的意外命名空间冲突: MyClass.__private就变成了 MyClass._MyClass__private(请注意 对于与 超类,例如不同模块中的子类) 从他们的类之外访问 __private名称,只是不方便和 脆弱(它在超类的确切名称上添加了一个依赖项)。

问题是,一个类的作者可能会合理地认为“这 属性/方法名应该是私有的,只能从内部访问 这个类定义”,并使用 __private约定, 该类的用户可以创建一个合法需要的子类 所以要么超类必须被修改 (这可能是困难的或不可能的) ,或子类代码必须 使用手工拼凑的名称(这样的名称充其量是丑陋和脆弱的)。

在 Python 中有一个概念: “我们都是成人协议” 你使用 __private表单,你是谁保护的属性? 使用来自 这是超类的责任 正确地记录他们的属性。

最好使用单前导下划线约定, “这根本不是名称错误,它只是表明 其他人则表示“小心处理这个问题,这是一个内部实现 细节; 如果你不完全理解,就不要触摸它” 不过这是惯例。