【问题标题】:private variables and property in pythonpython中的私有变量和属性
【发布时间】:2021-11-22 03:53:34
【问题描述】:

我在 python 中弄乱了属性描述符,但是弹出了一个有趣的错误(至少对我来说)(recursionerror)。这是导致它的代码


class Employer:

    def __init__(self, age, name):
        self.age = age
        self.name = name

    def get_age(self):
        return self.age

    def set_age(self, value):
        if value > 30:
            raise ValueError("Our company doesn't want old people")
        self.age = value

    def deleter(self):
        del self.age

    age = property(get_age, set_age, deleter)


emp = Employer(20, "Alex")

现在,在我将 setter 方法中的 self.age 更改为 self._age 并在 getter 和 deleter 方法中做了同样的事情之后,一切正常,但我真的不明白为什么。我查看了文档,但是我真的不明白这一点: “名称修饰有助于让子类覆盖方法而不破坏类内方法调用。”当我得到递归错误时,我认为某些东西被破坏了,但在我看来并没有。按照我的推理:

  1. 我定义了要存储在字典中的属性
  2. 我使用 self.attribute_name 修改该属性 我的意思是,当我尝试使用我的方法修改属性名称时,似乎某些东西已经在运行。有人可以将私有变量的概念与属性描述符联系起来,因为可能这就是问题所在。谢谢您的关注。李>

【问题讨论】:

    标签: python


    【解决方案1】:

    self.age 是具有设置器逻辑set_age 的描述符。每当执行self.age = ... 时,都会调用set_age

    由于对self.age 的赋值发生在set_age,因此您将获得无限递归。

    【讨论】:

    • @Not_here_to_play 我想你理解了这个问题。我不太明白你关于self._age 的问题,但也许这会有所帮助:self._age 的要点是将年龄值存储在“正常”实例变量中,该变量在访问时不会运行 getter 或 setter 逻辑(不像 @ 987654329@).
    • @Not_here_to_play 所以self.age 在被访问或设置时调用函数。这些函数可能对self._age 执行某些操作,其中存储了实际年龄值,对用户“隐藏”。
    • @Not_here_to_play self._age 是一个您没有定义为属性的普通实例变量,因此当您获取或设置它时不会运行 getter 或 setter 逻辑。在您的脑海中将self._age 重命名为self.the_numeric_age_value。它与self.age 完全解耦,您只是碰巧在get_ageset_age 的主体中访问/设置。
    • @Not_here_to_play "当我运行 print(self.age) 时,我到底如何得到 self._age 而不是 self.age" get_age 中返回 self._age
    • @Not_here_to_play _age 不是属性,它是一个普通的实例变量。如果它是像age 这样的属性,它将有自己的setter 和getter。
    【解决方案2】:

    您可以这样做以避免名称冲突。

    class Employer:
    
        def __init__(self, age, name):
            self.__age = age
            self.__name = name
        
        @property
        def age(self):
            return self.__age
    
        @age.setter
        def age(self, value):
            if value > 30:
                raise ValueError("Our company doesn't want old people")
            self.__age = value
    
        @age.deleter
        def age(self):
            del self.__age
    

    【讨论】:

      猜你喜欢
      • 2013-11-27
      • 2020-10-22
      • 1970-01-01
      • 2014-06-19
      • 2019-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多