# Python Property ## Overview ```python class dog: def __init__(self): self._name = "Bello" @property def name(self) -> str: print("Setter method called") return self._name @name.setter def name(self, name): if isinstance(name, str): self._name = name print("Getter method called") else: return ``` ```python snowy = dog() snowy.name = "Snowy" snowy.name ``` ```python Setter method called Getter method called 'Snowy' ``` ## Benefits - **@property**: for the caller name becomes an attribute (not a method any more) - no more use of parentheses when calling a getter: `a = snowy.name` instead of `a = snowy.name()` - the hidden getter still can return a deep copy or converted attribute (bytearray instead of byte, list instead of set, ...) - **@name.setter**: for the caller name can set by `=` - no more use of parentheses when calling a setter: `snowy.name = "Snowy"` instead of `snow.name("Snowy")` - the hidden setter still can use type checks or throw errors or do conversions
