如何只允许 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 而不是_xx 仍然不会变成私有的。所以_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 获取/设置变量值? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

Dart中类的getter和setter

用 mapState 和 mapMutations 替换计算的 getter/setter

iOS getter setter

getter和setter方法

是否可以在接口定义中使用 getter/setter?

为啥 GSON 使用字段而不是 getter/setter?