(18个答案)15小时前关门了。在Python中,什么时候应该使用_foo(下划线)或__bar(双下划线)作为私有成员和方法?
_foo
__bar
uubf1zoe1#
请注意,Python中并没有“私有方法”这样的东西,双下划线只是名字的变形:
>>> class A(object): ... def __foo(self): ... pass ... >>> a = A() >>> A.__dict__.keys() ['__dict__', '_A__foo', '__module__', '__weakref__', '__doc__'] >>> a._A__foo()
因此__前缀在你需要发生mangling时是很有用的,例如不与继承链上下的名字冲突。对于其他用途,单下划线会更好,恕我直言。EDIT,关于__上的混淆,PEP-8在这一点上非常清楚:如果你的类要被子类化,并且你有不想让子类使用的属性,考虑用双前导下划线而不是尾部下划线来命名它们。这会调用Python的名称变形算法,将类名变形为属性名。如果子类无意中包含同名属性,这有助于避免属性名冲突。注意3:不是每个人都喜欢名字篡改。尽量平衡避免意外的名字冲突和高级调用者的潜在使用。因此,如果你不希望子类意外地用相同的名字重新定义自己的方法,就不要使用它。
__
quhf5bfb2#
双下划线,它以这样一种方式修改名称,即不能简单地从类外部通过__fieldName访问名称,如果要使名称私有化,就应该从__fieldName开始(尽管访问该字段仍然不是很困难)。
__fieldName
class Foo: def __init__(self): self.__privateField = 4; print self.__privateField # yields 4 no problem foo = Foo() foo.__privateField # AttributeError: Foo instance has no attribute '__privateField'
它可以通过_Foo__privateField访问,但它会大喊“我是私人的,不要碰我”,这总比什么都没有好。
_Foo__privateField
htrmnn0y3#
双下划线。这会破坏变量名。变量仍然可以被访问,但是这样做通常是个坏主意。使用单下划线表示半私有(告诉python开发人员“只有在绝对必要时才更改”),双下划线表示完全私有。
w6mmgewl4#
因为那是编码约定。更多信息请参见here。
4条答案
按热度按时间uubf1zoe1#
请注意,Python中并没有“私有方法”这样的东西,双下划线只是名字的变形:
因此
__
前缀在你需要发生mangling时是很有用的,例如不与继承链上下的名字冲突。对于其他用途,单下划线会更好,恕我直言。EDIT,关于
__
上的混淆,PEP-8在这一点上非常清楚:如果你的类要被子类化,并且你有不想让子类使用的属性,考虑用双前导下划线而不是尾部下划线来命名它们。这会调用Python的名称变形算法,将类名变形为属性名。如果子类无意中包含同名属性,这有助于避免属性名冲突。
注意3:不是每个人都喜欢名字篡改。尽量平衡避免意外的名字冲突和高级调用者的潜在使用。
因此,如果你不希望子类意外地用相同的名字重新定义自己的方法,就不要使用它。
quhf5bfb2#
双下划线,它以这样一种方式修改名称,即不能简单地从类外部通过
__fieldName
访问名称,如果要使名称私有化,就应该从__fieldName
开始(尽管访问该字段仍然不是很困难)。它可以通过
_Foo__privateField
访问,但它会大喊“我是私人的,不要碰我”,这总比什么都没有好。htrmnn0y3#
双下划线。这会破坏变量名。变量仍然可以被访问,但是这样做通常是个坏主意。
使用单下划线表示半私有(告诉python开发人员“只有在绝对必要时才更改”),双下划线表示完全私有。
w6mmgewl4#
因为那是编码约定。更多信息请参见here。