【发布时间】:2018-11-15 08:11:42
【问题描述】:
我开始学习 Python 编程,有一段时间从未接触过公共/私有的概念。在用 Java 了解了这个概念之后,我仍然没有看到它有太多用处,并且一直很喜欢 Python 的“我们都是成年人”的原则。尤其是当通常的 get/set 方法将如此多的代码行添加到其他单行代码时。最终,在用 C++ 编写了大量项目之后,我开始了解它的好处,例如允许封装实现细节。它还清楚地表达了什么时候不应该直接设置变量,因为它的设置应该有副作用。
当我的 Python 程序变得足够大时,我经常忘记某个属性是否仅在内部使用,并且不知道该属性是否可以安全更改。通常我最终会更改属性,运行程序,遇到异常,修复相关代码中的错误,然后重复。在 Python 中,我们可以使用领先的下划线伪私有约定和属性函数来获得这些优势,同时仍然允许代码访问它想要的内容。
作为一个例子,这里是一个点类。属性 'x' 和 'y' 真的不应该被直接设置,因为 'distance' 属性需要随时重新计算(这也可能是一个足够复杂的表达式,每次重新计算都会花费太长时间)。
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)
我真的很喜欢后来的风格,但并没有真正广泛地使用它。制作大多数“公共”属性属性有什么缺点吗?我只能想到:
- 可读性?就我个人而言,后一种风格对我来说更具可读性,因为您在不实现该类时关心的任何属性都是清晰且最重要的。
- 其他开发人员不清楚?在个人项目中使用它时,这不是问题。但这显然遵循 Python 的规则,应该很容易理解。
- 效率较低?这是另一个间接层,因此这是可能的,但是属性访问通常不是一个非常有限的情况。
- 编写/设置没有那么快?不必为每个类和可能的添加都完全遵循这种风格,但可以在真正开始形成可靠的实现时添加。
- 不那么 Pythonic?可能,但我觉得 Pythonic 的标准不应该是任意的,并且与可读性和效率有关。
【问题讨论】:
-
你需要在你的第一个区块中修复
y属性return self._x->return self._y -
啊,谢谢你的收获!已经很晚了,但我想在忘记之前把这一切都弄清楚。
-
这个问题可能会因为主要基于意见而被关闭,但我认为这是一个在Python chat room 中讨论的好话题。
-
“这个问题可能会因为主要基于意见而被关闭”。我会为此投入资金。在software engineering 上提问可能会更好
-
Python 属性的好处是类的编写者不必预先决定是使用简单属性还是使用 getter 和 setter 方法,并且类的用户也不需要知道或关心他们正在访问的属性是简单属性还是属性
标签: python properties encapsulation