Python中的私有变量和方法
在Python中,我什么时候应该用_foo
(一个下划线)或者__bar
(两个下划线)来表示私有成员和方法呢?
4 个回答
11
双下划线。这会让变量名变得复杂。虽然这个变量还是可以访问,但通常这样做不是个好主意。
单下划线用来表示半私有(告诉其他Python开发者“只有在绝对必要时才可以修改”),而双下划线则表示完全私有。
44
双下划线的作用是让名字变得复杂,这样外部就不能简单地通过 __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
来访问它。但这就像在大喊“我很私密,别碰我”,总比什么都没有好。
72
请注意,Python中并没有所谓的“私有方法”。双下划线只是用来改变名字的方式:
>>> class A(object):
... def __foo(self):
... pass
...
>>> a = A()
>>> A.__dict__.keys()
['__dict__', '_A__foo', '__module__', '__weakref__', '__doc__']
>>> a._A__foo()
因此,当你需要这种名字改变的效果时,使用__
前缀是有用的,比如为了避免在继承链上出现名字冲突。对于其他情况,我认为单下划线会更好。
补充一下,关于__
的混淆,PEP-8对此有很清楚的说明:
如果你的类是打算被继承的,并且你有一些属性不希望子类使用,考虑用双下划线开头而不加结尾的下划线来命名它们。这会触发Python的名字改变算法,把类名变成属性名。这样可以避免子类意外地包含同名属性而导致的冲突。
注意3:并不是每个人都喜欢名字改变的方式。要在避免意外名字冲突和高级用户可能使用的需求之间找到平衡。
所以,如果你不担心子类会意外地重新定义同名的方法,就不用使用这个方式。