在 Python 中,为什么在从 getter() 访问私有属性时最终会以递归结束,而没有在 getter() 中使用双下划线

In Python ,why does it end up in recursion while accessing private attribute from getter() ,without using double underscore in getter()

提问人:Armaan Sahoo 提问时间:8/31/2023 最后编辑:Armaan Sahoo 更新时间:8/31/2023 访问量:47

问:

class Person():

    def __init__(self,name:str,height :float) -> None:
        #initialize
        self.__name=name
        self.height=height
    
    @property
    def name(self) -> str:
        print("Inside Getter")
        return self.__name
    
    @name.setter
    def name(self, value):
        print("New name being set")
        self.name = value

    def __repr__(self) -> str:
        return f"({self.__class__.__name__}:{self.name},{self.height})"

p=Person("Sam",180.00)
print(p)

1.In 上面的代码,当我在repr()方法中访问名称而不使用双下划线时,它会调用getter,然后调用repr()。我不明白为什么在这里调用 getter。(当我在 repr() 中使用双下划线时,代码也按预期工作,只有 repr() 被执行)

上述代码的输出为:

内部 Getter

(人:Sam,180.0)

-----------------------------------------------------------------------------------------------------------------------------

2.当我也从 getter() 中删除双下划线时,稍微修改了上面的代码(现在 getter() 和 repr() 都没有双下划线)

 def name(self) -> str:
        print("Inside Getter")
        return self.name

我最终得到了一个递归错误。递归是如何发生的?

in name print(“Inside Getter”) RecursionError:调用 Python 对象时超出最大递归深度

python oop getter-setter 封装私有 成员

评论

1赞 Iain Shelvington 8/31/2023
你在方法中获取/访问name属性/属性,为什么你认为getter不会被调用?__repr__
2赞 Iain Shelvington 8/31/2023
这是意料之中的,你得到的是一个不同的属性,与你的属性/描述符的名称不同,该属性被命名为“name”而不是“__name”
1赞 deceze 8/31/2023
name是 getter。 是一个完全不同的属性。如果你在 getter 中得到 getter,那么你只能在 getter 中得到 getter,并且可以在得到 getter 的同时得到 getter,dawg。— 顺便说一句,在二传手中也有同样的问题,你只是还没有遇到过。__name__name
1赞 CtrlZ 8/31/2023
Python 类中没有私有属性这样的东西。编码人员倾向于使用前导下划线来指示属性应被视为“私有”,但这只是一种常见的约定
1赞 deceze 8/31/2023
因为这正是它的用途:名称篡改以防止这种幼稚的访问。如果你再努力一点,你仍然可以得到这个属性。__

答:

0赞 Nostril 8/31/2023 #1

关于递归,当你访问时,你实际上是在调用属性self.name

@property
def name(self) -> str:
    print("Inside Getter")
    return self.__name

因此,如果您尝试在属性访问,您将设置一个递归循环。self.name

通常,你会使用该属性来存储要在 getter 和 setter 后面混淆的数据,因此你的类将如下所示:self.__name

class Person():

    def __init__(self, name:str, height:float) -> None:
        self.name = name
        self.height = height
    
    @property
    def name(self) -> str:
        return self.__name # Get self.__name
    
    @name.setter
    def name(self, value):
        self.__name = value # Set self.__name

    def __repr__(self) -> str:
        return f"({self.__class__.__name__}:{self.name},{self.height})"