我开始用Python学习编程,并且有一段时间没有接触过public / private的概念。在学习了Java的概念之后,我仍然没有看到它的太多用途,并且总是喜欢Python的“我们都是成年人”的原则。尤其是当通常的get / set方法向单行添加了如此多的代码行时。最终,在用C ++编写大量项目后,我开始了解它的好处,例如允许封装实现细节。它还清楚地表明了何时不应直接设置变量,因为其设置应具有副作用。
当我的Python程序变得足够大时,我常常会忘记一个属性是否仅在内部使用,并且不知道该属性是否可以安全更改。通常,我最终会更改属性,运行程序,遇到异常,修复相关代码中的错误并重复执行。在Python中,我们可以使用领先的下划线pseduo-private约定和属性函数来获得这些优势,同时仍然允许代码访问所需的内容。
作为一个例子,这里是一个点类。实际上,不允许直接设置属性“ x”和“ y”,因为“距离”属性需要随时重新计算(这可能是一个非常复杂的表达式,每次重新计算都将花费很长时间)。
class Point:
def __init__(self, x, y):
self._x = x
self._y = y
self._distance = (x**2 + y**2) ** (1/2)
@property
def x(self):
return self._x
@property
def y(self):
return self._x
@property
def distance(self):
return self._distance
如果您的属性是只读的,则代码可以非常简洁。
class Point:
x = property(lambda self: self._x)
y = property(lambda self: self._y)
distance = property(lambda self: self._distance)
def __init__(self, x, y):
self._x = x
self._y = y
self._distance = (x**2 + y**2) ** (1/2)
我真的很喜欢后来的风格,但是并没有广泛使用它。设置大多数“公共”属性有什么缺点吗?我只能想到:
答案 0 :(得分:0)
在必要时将属性设为只读。默认情况下,不要将每个attr设为只读。
使用属性实现只读属性没有错。这就是属性成为Python一部分的原因之一。另一方面,将大多数属性设置为只读并没有什么特别的权利。它违反了标准的Python习惯用法,使您的类难以与之交互(特别是在您自己的代码库中)。请记住,Python中没有C ++ private
关键字的实际等效项。例如,即使x
是只读的,也没有阻止用户致力于用脚self._x = 19
射击自己的行为。
通常,使用领先的下划线_name
标记内部属性和公共属性就足够了:
class Foo:
def __init__(self, bar, baz):
self._mine = bar
self.public = baz
按照设计,您的x
类的y
和Point
属性是只读属性的理想选择。但是,我想说,灵活地设计类并将距离设为方法更像Pythonic:
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def distance(self):
return (x**2 + y**2) ** (1/2)
或者,如果性能存在问题,请将distance
保留为属性,但是只要x
或y
发生更改,就重新对其进行计算:
class Point:
@staticmethod
def _distance(x, y):
return (x**2 + y**2) ** (1/2)
@property
def x(self):
return self._x
@x.setter
def x(self, x):
self._x = x
self._distance = Point._distance(x, self._y)
@property
def y(self):
return self._y
@y.setter
def y(self, y):
self._y = y
self._distance = Point._distance(self._x, y)
distance = property(lambda self: self._distance)
def __init__(self, x, y):
self._x = x
self._y = y
self._distance = Point._distance(x, y)