如何只允许 getter/setter 获取/设置变量值? [复制]
Posted
技术标签:
【中文标题】如何只允许 getter/setter 获取/设置变量值? [复制]【英文标题】:How to allow only getter/setter to get/set variable value? [duplicate] 【发布时间】:2020-01-11 13:40:56 【问题描述】:在此示例中,用户仍然可以使用以下方法访问和设置变量:
obj = C()
obj._x=10
varA = obj._x
即使我们在下面的代码中使用__x
而不是_x
,x
仍然不会变成私有的。所以_x
的唯一目的是让程序员知道它不是直接通过obj._x
设置的?
class C:
def __init__(self):
self._x = None
@property
def x(self):
"""I'm the 'x' property."""
return self._x
@x.setter
def x(self, value):
self._x = value
@x.deleter
def x(self):
del self._x
【问题讨论】:
没有。 Python 是一种用于“同意的成年人”的语言;也就是说,我们可以通过前导下划线指示变量是私有的,但我们不会像 C++/C#/Java 那样强制执行隐私。双下划线有一个特定的目的:模仿其他语言的访问修饰符不是那个目的。 即使是前导双下划线也不会阻止修改,只会让它“更难”***.com/questions/1301346/… Python 没有私有的。甚至没有双下划线名称修改。这不是双下划线名称修饰的目的。您使用属性的示例不是您应该做的。 好吧,在这个例子中,属性的目的是确保当使用 obj.x 分配或获取值时,它会调用适当的 getter/setter,如果有的话,它将应用逻辑然后分别从/到_x获取/设置值 @variable 在这种情况下,您应该(可能)将属性分配给 everywhere,即使在__init__
中也是如此,而不是绕过并直接分配给 _x
.
【参考方案1】:
在 Python 中,使用 _var_name
来表示某些东西是私有的是一种约定,但它不像在 C++、C#、Java 等语言中那样强制执行它。
双下划线前缀会导致 Python 解释器重写属性名称以避免子类中的命名冲突。
这也称为名称修改——解释器更改变量名称的方式使得以后扩展类时更难产生冲突。
考虑以下示例
class Test:
def __init__(self):
self.foo = 11
self._bar = 23
self.__baz = 23
现在,让我们运行以下代码:
>>> t = Test()
>>> dir(t)
['_Test__baz', '__class__', '__delattr__', '__dict__', '__dir__',
'__doc__', '__eq__', '__format__', '__ge__', '__getattribute__',
'__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__',
'__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
'__setattr__', '__sizeof__', '__str__', '__subclasshook__',
'__weakref__', '_bar', 'foo']
dir(t)
为我们提供了一个包含对象属性的列表。当您在该列表中搜索 __baz
时,您会看到没有具有该名称的变量。如果你仔细观察,你会发现这个对象上有一个名为_Test__baz
的属性。这是 Python 解释器应用的名称修饰。
【讨论】:
好的,所以即使删除单个下划线在技术上也没有任何区别 @variable,它没有。正如用户snakecharmerb
告诉你的那样。这是一个约定俗成的约定,因此您可以简单地违反规则,但 Pythonistas 同意遵守它。
@variable 同样,Python 没有私有变量。 It says that right in the documentation。如果您正在寻找它,请使用另一种语言
@juanpa.arrivillaga,非常感谢您提供文档链接。
属性的目的是确保当使用 obj.x 分配或获取值时,它会调用适当的 getter/setter,如果有的话,它将应用逻辑,然后从/to _x 分别是?以上是关于如何只允许 getter/setter 获取/设置变量值? [复制]的主要内容,如果未能解决你的问题,请参考以下文章