使用变量和方法的Underscore vs Double下划线

Jor*_*ell 127 python

有人很好地向我解释__method()破坏但是由于有很多其他人需要帮助而没有进一步打扰他,我想知道是否有人可以进一步详细说明差异.

例如,我不需要修改但是保持私有所以有人不能做instance._method()?或者它是否只是通过使其独一无二来覆盖另一个变量?我不需要我的内部方法"隐藏",但由于它们是特定的使用我不希望它们在课外使用.

nmi*_*els 235

PEP 8:

  • _single_leading_underscore:弱"内部使用"指标.例如

    from M import *

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

  • single_trailing_underscore_:用于避免与Python关键字冲突的约定,例如

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

  • __double_leading_underscore:在命名类属性时,调用名称修改(在类内部FooBar,__boo变为_FooBar__boo;见下文).

  • __double_leading_and_trailing_underscore__:生成在用户控制的命名空间中的"魔术"对象或属性.例如__init__, __import____file__.不要发明这样的名字; 只记录使用它们.

此外,David Goodger的代码就像Pythonista一样:

属性:interface,_internal,__private

但要尽量避免这种__private形式.我从不使用它.相信我.如果你使用它,你会后悔的.

说明:

来自C++/Java背景的人特别容易过度使用/滥用这个"功能".但是__private名称与Java或C++中的名称不同.它们只是触发一个名称修改,其目的是防止子类中的意外命名空间冲突: MyClass.__private只是成为MyClass._MyClass__private.(请注意,即使这样,对于与超类同名的子类也会出现问题,例如不同模块中的子类.)可以__private从类外部访问名称,只是不方便和脆弱(它增加了对确切名称的依赖性)超类).

问题是类的作者可能合法地认为"此属性/方法名称应该是私有的,只能从此类定义中访问"并使用该__private约定.但是稍后,该类的用户可能会创建一个合法需要访问该名称的子类.因此,要么必须修改超类(可能很难或不可能),要么子类代码必须使用手动损坏的名称(最好是丑陋且易碎).

Python中有一个概念:"我们都同意这里的成年人".如果您使用该__private表单,您是谁保护该属性?子类的责任是正确使用超类中的属性,超类负责正确记录其属性.

最好使用单引导下划线约定 _internal."这不是在名都缺胳膊少腿,它只是表示给别人"小心这一点,它是一个内部实现细节; 如果你不完全理解它,请不要碰它."这只是一个惯例.

  • 我并没有真正遵循为什么不使用私有方法的解释 - 我的意思是在Java和Co中可以使用完全相同的参数,但到目前为止,虽然Java程序使用了大量私有方法(但不能由子类使用) (17认同)
  • 在其他语言中,将字段/方法从私有更改为公共只意味着单行更改(在定义中将"private"关键字更改为"public").在Python中,您必须更改属性名称,这意味着在调用它的位置也要更改它.不完全是PITA,但更容易出错. (10认同)
  • 我同意“我们都是同意的成年人”,但由于 python 支持后期绑定,所以这可能很危险。您可能会意外地覆盖子类的方法,从而破坏代码。没有任何东西会告诉你你这样做了,而且很难发现。IDE 应该支持与此相关的警告。有人知道支持此类警告的好IDE吗?就像 Visual Studio 对 c# 所做的那样。 (2认同)

Ned*_*der 113

单个前导下划线只是一种惯例,意思是"你可能不应该使用它".它没有阻止某人使用该属性.

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


Cat*_*lus 11

Python中没有访问控制.您可以访问类的所有属性,包括错位名称(as _class__variable).专注于您的代码和API,而不是试图保护开发人员自己.