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 the above code ,when I access the name without using double underscore inside repr() method, it calls getter and then calls repr(). I don't understand why getter gets called here. (Code works as expected when I use double underscore inside repr() too, only repr() gets executed )

Output for the above code is:

Inside Getter

(Person:Sam,180.0)

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

2.Slightly modifying the above code when I also remove the double underscore from the getter()(now both getter() and repr() don't have a double underscore)

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

I end up with an recursion error. How did recursion take place here?

in name print("Inside Getter") RecursionError: maximum recursion depth exceeded while calling a Python object

1

There are 1 best solutions below

0
Nostril On BEST ANSWER

Regarding the recursion, when you access self.name you are actually calling the property

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

so if you try to access self.name within the property, you'll have set up a recursive loop.

Typically, you'd use the self.__name attribute to store the data that you want to obfuscate behind getters and setters, so your class would look like this:

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})"