当有 getter/setter 时访问私有变量
我有一个关于 Python 编程的正确方式的问题...也许可能有几种不同的意见,但事情是这样的:
假设我有一个带有几个私有属性的类,并且我已经实现了两个 getter/setter(不是重载 __getattr__
和 __setattr__
,但以更“Java-tistic”的风格):
class MyClass:
def __init__(self):
self.__private1 = "Whatever1"
def setPrivate1(self, private1):
if isinstance(private1, str) and (private1.startswith("private")):
self.__private1 = private1
else:
raise AttributeError("Kaputt")
def getPrivate1(self):
return self.__private1
现在让我们说下面几行,在同一个类的另一个方法中,我需要重新设置“__private1”的值。由于它是同一个类,我仍然可以直接访问私有属性 self.__private1。
我的问题是:我应该使用:
self.setPrivate1("privateBlaBlaBla")
还是应该直接访问为:
self.__private1 ="privateBlaBlaBla"
因为我是设置新值的人,所以我知道所述值(“privateBlaBlaBla”)是正确的(以“private”开头的 str()),所以它不会导致系统不一致。另一方面,如果另一个程序员采用了我的代码,并且需要更改 self.__private1 属性的功能,他将需要检查所有代码,并查看 __private1 的值是否已在其他地方手动设置。
我的猜测是,正确的做法是始终使用 setPrivate1 方法,并且只直接访问 get/set 中的 __private1 变量,但我想知道更有经验的 Python 程序员的意见。
I have a question about righteous way of programming in Python... Maybe there can be several different opinions, but here it goes:
Let's say I have a class with a couple of private attributes and that I have implemented two getters/setters (not overloading __getattr__
and __setattr__
, but in a more “Java-tistic” style):
class MyClass:
def __init__(self):
self.__private1 = "Whatever1"
def setPrivate1(self, private1):
if isinstance(private1, str) and (private1.startswith("private")):
self.__private1 = private1
else:
raise AttributeError("Kaputt")
def getPrivate1(self):
return self.__private1
Now let's say a few lines below, in another method of the same class, I need to re-set the value of that “__private1”. Since it's the same class, I still have direct access to the private attribute self.__private1.
My question is: Should I use:
self.setPrivate1("privateBlaBlaBla")
or should I access directly as:
self.__private1 ="privateBlaBlaBla"
since I am the one setting the new value, I know that said value (“privateBlaBlaBla”) is correct (an str() that starts with “private”), so it is not going to leave the system inconsistent. On the other hand, if another programmer takes my code, and needs to change the functionality for the self.__private1 attribute, he will need to go through all the code, and see if the value of __private1 has been manually set somewhere else.
My guess is that the right thing to do is to always using the setPrivate1 method, and only access directly the __private1 variable in the get/set, but I'd like to know the opinion of more experienced Python programmers.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
你不能提出一个糟糕的 Python 的典型例子,然后期望人们就如何处理它提出意见。使用 getter 和 setter。
旁注——使用双下划线名称可能会令人困惑,因为 Python 实际上会破坏名称以阻止您从类外部访问它们。这并不能提供真正的安全性,反而会带来无穷无尽的麻烦。避免麻烦的最简单方法是使用单下划线名称,这基本上是
private
的通用约定。 (是的。)如果你想要发表意见——请使用属性 =)。如果你想对你的 JavaPython 怪物发表意见,我会使用 setter —— 毕竟,你已经编写了它,这就是它的用途!手动设置变量没有明显的好处,但有几个缺点。
You can't present a classic example of bad Python and then expect people to have opinions on what do to about it. Use getters and setters.
A side comment -- using double underscore names can be confusing, because Python actually mangles the name to stop you accessing them from outside the class. This provides no real security, but causes no end of headaches. The easiest way to avoid the headaches is to use single-underscore names, which is basically a universal convention for
private
. (Ish.)If you want an opinion -- use properties =). If you want an opinion on your JavaPython monstrosity, I would use the setter -- after all, you've written it, that's what it's there for! There's no obvious benefit to setting the variable by hand, but there are several drawbacks.
两者都不。 在 Python 中,使用属性,不是 getter 和 setter。
然后稍后在您的代码中,设置
_private1
属性Neither. In Python, use properties, not getters and setters.
Then later on in your code, set the
_private1
attribute with@unutbu 发布了一个很好的答案,但我会有所不同。我认为当您使用 setter 和属性方法时,可以将
__init__< 内的
self._private1 = "Whatever1"
替换为self.private1 = "Whatever1"
/代码>。重写上面的类:这允许用其他任何内容替换 _private1,而不会更改或破坏其他类使用的类的接口。
@unutbu has posted a nice answer but I will differ a bit. I think when you use the setter and property approach then
self._private1 = "Whatever1"
can be replaced withself.private1 = "Whatever1"
inside the__init__
. Rewriting the above class:This allows to substitute _private1 by anything else without changing or breaking the class's interface used by other classes.