【问题标题】:Accessing private variables when there's a getter/setter for them在有 getter/setter 时访问私有变量
【发布时间】:2021-04-06 00:25:28
【问题描述】:

我有一个关于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 程序员的意见。

【问题讨论】:

  • __ 名称重整使得这不能很好地工作。

标签: python oop private-members


【解决方案1】:

你不能给出一个糟糕的 Python 的经典例子,然后期望人们对如何处理它有意见。使用 getter 和 setter。

class MyClass:
    def __init__(self):   
        self._private1 = "Whatever1"

    @property
    def private1(self):
        return self._private1

    @private1.setter
    def private1(self, value):
        self._private1 = value

旁注——使用双下划线名称可能会造成混淆,因为 Python 实际上会破坏名称以阻止您从类外部访问它们。这并没有提供真正的安全性,但也带来了无穷无尽的麻烦。避免头痛的最简单方法是使用单下划线名称,这基本上是private 的通用约定。 (伊什。)


如果您想发表意见 - 使用属性 =)。如果您想对您的 JavaPython 怪物发表意见,我会使用 setter —— 毕竟,您已经编写了它,这就是它的用途!手动设置变量没有明显的好处,但有几个缺点。

【讨论】:

  • +1 其中两个缺点是:(1)您必须输入名称被破坏的怪物;(2)如果 setter 将来开始做重要的工作,它可能会引入细微的错误。
  • 这很酷,这是我没有注意的事情,但它似乎不适用于 python 2.4(setter 部分),即使我从“object”扩展我的类(不过,在 2.6 上运行良好)
  • @BorrajaX:在Python2.4中,使用private1 = property(getx,setx),其中getx是getter函数,setx是setter。见docs.python.org/library/functions.html#property
  • @unutbu:是的,我明白为什么它在 2.4 (en.wikipedia.org/wiki/Python_syntax_and_semantics#Properties) 上工作不那么直接了,但是您的回答非常有帮助! :-) 非常感谢!说实话,我并没有太注意装饰器,但它们真的很有趣。
【解决方案2】:

两者都不是。 In Python, use properties,不是 getter 和 setter。

class MyClass:

    def __init__(self):   
        self._private1 = "Whatever1"
    @property
    def private1(self):
        return self._private1
    @private1.setter
    def private1(self, private1):
        if isinstance(private1, str) and (private1.startswith("private")):
            self._private1 = private1
        else:
            raise AttributeError("Kaputt")

然后稍后在您的代码中,将_private1 属性设置为

self.private1="privateBlaBlaBla"

【讨论】:

    猜你喜欢
    • 2014-03-27
    • 2013-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多