当有疑问时,将其保留为“公共”-我的意思是,不要添加任何东西来模糊属性的名称。如果您有一个具有某些内部值的类,请不要为它操心。而不是写:class Stack(object):
def __init__(self):
self.__storage = [] # Too uptight
def push(self, value):
self.__storage.append(value)
默认情况下写这个:class Stack(object):
def __init__(self):
self.storage = [] # No mangling
def push(self, value):
self.storage.append(value)
这无疑是一种有争议的做事方式。Python新手只是讨厌它,甚至有些老Python人也鄙视这个默认,但它是默认的,所以我真的建议你遵循它,即使你觉得不舒服。
如果你真的想发送信息“不能碰这个!”对于用户来说,通常的方法是在变量前面加上一下划线。这只是一种惯例,但人们理解它,在处理这些事情时要加倍小心:class Stack(object):
def __init__(self):
self._storage = [] # This is ok but pythonistas use it to be relaxed about it
def push(self, value):
self._storage.append(value)
这对于避免属性名和属性名之间的冲突也很有用:class Person(object):
def __init__(self, name, age):
self.name = name
self._age = age if age >= 0 else 0
@property
def age(self):
return self._age @age.setter def age(self, age):
if age >= 0:
self._age = age else:
self._age = 0
那双下划线呢?嗯,双下划线魔法主要用于避免方法的意外重载和名称与超类属性的冲突..如果您编写的类需要多次扩展,则非常有用。
如果您想将它用于其他目的,您可以使用,但它既不常见,也不建议使用。
编辑:为什么会这样?好吧,通常的Python风格并不强调让事情变得私密-恰恰相反!有很多原因-大多数都有争议.让我们看看其中的一些。
Python具有属性
如今,大多数面向对象语言都使用相反的方法:不应该使用的东西不应该是可见的,因此属性应该是私有的。理论上,这将产生更易于管理、耦合更少的类,因为没有人会鲁莽地更改对象内的值。
然而,这并不是那么简单。例如,Java类确实有很多属性和只是到达价值和策划人集价值。假设您需要七行代码来声明单个属性-Python程序员会说这是不必要的复杂。另外,在实践中,您只需编写大量代码来获得一个公共字段,因为您可以使用getter和setter来更改其值。
那么,为什么要遵循这种默认的私人政策呢?默认情况下,只需公开属性即可。当然,这在Java中是有问题的,因为如果您决定向属性添加一些验证,则需要更改所有person.age = age;
在你的代码中,让我们说,person.setAge(age);
setAge()存在:public void setAge(int age) {
if (age >= 0) {
this.age = age;
} else {
this.age = 0;
}}
因此,在Java(和其他语言)中,默认情况是无论如何使用getter和setter,因为它们编写起来可能很烦人,但如果您发现自己处于我所描述的情况中,则可以节省大量时间。
但是,您不需要使用Python进行操作,因为Python具有属性。如果你有这门课:class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
然后决定验证年龄,不需要更改person.age = age你的代码片段。只需添加一个属性(如下所示)class Person(object):
def __init__(self, name, age):
self.name = name
self._age = age if age >= 0 else 0
@property
def age(self):
return self._age @age.setter def age(self, age):
if age >= 0:
self._age = age else:
self._age = 0
如果你还能用person.age = age,为什么要添加私有字段、getter和setter?
不管怎样,一切都是可见的-而试图隐藏只会使你的工作复杂化。
即使在有私有属性的语言中,您也可以通过某种反射/内省库来访问它们。人们做了很多,在框架和解决紧急需要。问题是,内省库只是一种很难用公共属性做的事情。
由于Python是一种非常动态的语言,因此将这种负担添加到类中只会适得其反。
这个问题是不可能看到的-它是所需看
对于Pythonsta来说,封装不是无法看到类的内部,而是避免查看它的可能性。我的意思是,封装是组件的属性,它允许使用组件,而不需要用户关心内部细节。如果您可以使用组件而不为其实现而烦恼,那么它将被封装(Python程序员的意见)。
现在,如果您以这样的方式编写类-您可以不用考虑实现细节就可以使用它-如果您想要因为某种原因而进入课堂。关键是:您的API应该是好的,其余的应该是细节。
吉多这么说
嗯,这是没有争议的:他是这么说的,实际上..(寻找“开放和服”)
这就是文化
是的,有一些原因,但没有关键的原因。这主要是Python编程的一个文化方面。坦率地说,这也可能是另一种方式-但事实并非如此。另外,您也可以轻松地问另一个问题:为什么某些语言默认使用私有属性?由于与Python实践相同的主要原因:因为它是这些语言的文化,每种选择都有其优点和缺点。
既然已经有了这种文化,我们建议你遵循它。否则,Python程序员告诉您删除__当您在堆栈溢出中问题时:)