Try this: Python Property

The sample code is:

class C(object):
    def __init__(self):
        self._x = None

    @property
    def x(self):
        """I'm the 'x' property."""
        print("getter of x called")
        return self._x

    @x.setter
    def x(self, value):
        print("setter of x called")
        self._x = value

    @x.deleter
    def x(self):
        print("deleter of x called")
        del self._x


c = C()
c.x = 'foo'  # setter called
foo = c.x    # getter called
del c.x      # deleter called
Answer from Grissiom on Stack Overflow
🌐
GeeksforGeeks
geeksforgeeks.org › python › getter-and-setter-in-python
Getter and Setter in Python - GeeksforGeeks
July 11, 2025 - The get_age() method is the getter, which retrieves the value of _age. The set_age() method is the setter, which assigns a value to _age.
🌐
GeeksforGeeks
origin.geeksforgeeks.org › getter-and-setter-in-python
Getter and Setter in Python | GeeksforGeeks
March 22, 2025 - The get_age() method is the getter, which retrieves the value of _age. The set_age() method is the setter, which assigns a value to _age.
Discussions

Having a hard time understanding getters and setters
tl;dr - getters and setters are used so that people creating classes can upgrade classes without breaking the code of those that use them. Getters and setters wrap attributes as methods, allowing you to use functionality only available through methods. In Python, we don’t use getters and setters because we have properties, which allow us to make attributes look like methods after the fact. —- To really understand getters and setters means understanding class design, understanding the potential problems with accessing object attributes, understanding why some languages use getters and setters, and finally understanding why we do not need getters and setters in Python. Imagine designing a class, but for a library, a library that people other than you will use. You might design a class once and then you are done with it, but in all likelihood you’ll want to design it in a way where you can upgrade the functionality of it if you need to, so you need to design it in a futureproof way. The most important thing here is to ensure that, when you do upgrade your class with new functionality, you do it in a way that does not break the code of the people that are using it. This is the concept of backwards compatibility - your new class can be used by people who write code against the older class. The importance of this cannot be understated - if you continuously break people’s code every time you upgrade your own, no one will want to use your code, ever. To ensure backwards compatibility, all the things that the people who write code access in your class access must not change. This means - the library import, the class name, the method names, the method parameters, what the method returns, and the attributes of the class - all these must be unchanged. All these aspects make up what is known as the public API of your class, and changing these means breaking backwards compatibility. Now, consider writing code for such a class. For a complicated method, you may wish to refactor its code into multiple sub-methods. Or, you may need to store attributes on your class for reasons of convenience. Having these as part of your public API would be undesirable, partly because the people using your library class do not need to access these, but mostly because if they end up using them, it’ll hamper your ability to upgrade your class in the future. These end up being private methods and attribute - these are not meant to be accessible by people who use your code and you are free to change them should you need to in the future. Languages like C++ and Java let you label functions and attributes as public and private, and people using your library class will be barred from accessing private elements. In Python, there is no public or private - instead you name your private elements giving it a prefix of a single underscore (i.e. self._bar instead of self.bar), and whilst calling code can access these underscore variables, they understand that they generally must not unless they absolutely have to. An important part of protecting your public API is also related to attributes. Attribute access is very limited - you can get a value from an attribute, set a value onto an attribute, and delete an attribute entirely (get, set and delete) - and that’s about it. The problem is, when you upgrade your class, you may end to wanting to do something more. For example, you may want to add validation - i.e. you may want to raise an exception if someone assigns an incorrect value to an attribute. Or you might want to change one attribute to retrieve data from another place - a classic example is a class that provides temperature for something in both Celsius and Fahrenheit, the attribute for one should just get the attribute for the other and then do the C-to/from-F conversion. These are things that can be done only by methods, not attributes, and if you use an attribute as part of your public API you can’t upgrade your class to use these things without breaking the code of those that use your class, because they are accessing an attribute (self.bar) rather than a method (self.bar()). This is where getters and setters come into play. Languages like Java and C++ use these. The concept is simple - have your attributes as private (i.e. self._bar), and then wrap your private attributes in public methods. This is how it looks in Python: def get_bar(self): return self._bar def set_bar(self, val): self._bar = val The people that use your code then use self.get_bar() and self.set_bar() when interacting with your class. Because they are interacting with a method, you can upgrade your class with the above functionality described, without breaking your public API. Getters and setters solve an important problem, but they are not without problems - the biggest being that they are fugly. The people that use your code have to do self.get_bar() rather than self.bar. But the bigger problem is for you, the creator of the class, who has to litter your code with getters and setters, regardless of whether you need them or not. You may never need to upgrade your class in the future, but you’ll need to use getters and setters if you want to expose an attribute, just on the off chance you’ll need it. Python solves this problem with properties. Properties allow for attributes to be converted into methods, but still be accessed as attributes. You, as the creator of a class, use public attributes when required (self.bar). When you upgrade your class, if and only if you need the functionality of a method, you use a property. You convert your public attribute into a private one (self._bar) and then you use the below syntax: @property def bar(self): return self._bar @bar.setter def bar(self, val): self._bar = val People who call your code still access the same way as an attribute (self.bar) but you now have a method under the hood, so you can use functionality that only methods can do, without breaking your public API for your users. And you only add properties when you need them, so you don’t litter your code like you would with getters and setters. More on reddit.com
🌐 r/learnpython
13
8
May 7, 2022
Use Properties rather than Getters & Setters in Python.

I'm still a Python noob in many ways. I'm trying to grasp the details of this tip and have a few questions.

First, I've never used explicit getter and setter methods. Is this simply a way to get more functionality from the default behavior? Like, in this example, being able to stop someone from overwriting a name once it has been assigned?

Second, I've never used del before in a script. I presume it is a built-in that deletes a property value from an object. My question is why does del hit the @name.deleter code? What ties them together? Is it as simple as this: if customer deleter code exists in the class, it will get called when del is called?

More on reddit.com
🌐 r/pythontips
7
48
October 29, 2012
🌐
GeeksforGeeks
gdevtest.geeksforgeeks.org › getter-and-setter-in-python
Getter and Setter in Python - GeeksforGeeks
December 4, 2019 - Getters and Setters in python are often used when: We use getters & setters to add validation logic around getting and setting a value. To avoid direct access of a class field i.e. private variables cannot be accessed directly or modified by ...
Top answer
1 of 9
1159

Try this: Python Property

The sample code is:

class C(object):
    def __init__(self):
        self._x = None

    @property
    def x(self):
        """I'm the 'x' property."""
        print("getter of x called")
        return self._x

    @x.setter
    def x(self, value):
        print("setter of x called")
        self._x = value

    @x.deleter
    def x(self):
        print("deleter of x called")
        del self._x


c = C()
c.x = 'foo'  # setter called
foo = c.x    # getter called
del c.x      # deleter called
2 of 9
628

What's the pythonic way to use getters and setters?

The "Pythonic" way is not to use "getters" and "setters", but to use plain attributes, like the question demonstrates, and del for deleting (but the names are changed to protect the innocent... builtins):

value = 'something'

obj.attribute = value  
value = obj.attribute
del obj.attribute

If later, you want to modify the setting and getting, you can do so without having to alter user code, by using the property decorator:

class Obj:
    """property demo"""
    #
    @property            # first decorate the getter method
    def attribute(self): # This getter method name is *the* name
        return self._attribute
    #
    @attribute.setter    # the property decorates with `.setter` now
    def attribute(self, value):   # name, e.g. "attribute", is the same
        self._attribute = value   # the "value" name isn't special
    #
    @attribute.deleter     # decorate with `.deleter`
    def attribute(self):   # again, the method name is the same
        del self._attribute

(Each decorator usage copies and updates the prior property object, so note that you should use the same name for each set, get, and delete function/method.)

After defining the above, the original setting, getting, and deleting code is the same:

obj = Obj()
obj.attribute = value  
the_value = obj.attribute
del obj.attribute

You should avoid this:

def set_property(property,value):  
def get_property(property):  

Firstly, the above doesn't work, because you don't provide an argument for the instance that the property would be set to (usually self), which would be:

class Obj:

    def set_property(self, property, value): # don't do this
        ...
    def get_property(self, property):        # don't do this either
        ...

Secondly, this duplicates the purpose of two special methods, __setattr__ and __getattr__.

Thirdly, we also have the setattr and getattr builtin functions.

setattr(object, 'property_name', value)
getattr(object, 'property_name', default_value)  # default is optional

The @property decorator is for creating getters and setters.

For example, we could modify the setting behavior to place restrictions the value being set:

class Protective(object):

    @property
    def protected_value(self):
        return self._protected_value

    @protected_value.setter
    def protected_value(self, value):
        if acceptable(value): # e.g. type or range check
            self._protected_value = value

In general, we want to avoid using property and just use direct attributes.

This is what is expected by users of Python. Following the rule of least-surprise, you should try to give your users what they expect unless you have a very compelling reason to the contrary.

Demonstration

For example, say we needed our object's protected attribute to be an integer between 0 and 100 inclusive, and prevent its deletion, with appropriate messages to inform the user of its proper usage:

class Protective(object):
    """protected property demo"""
    #
    def __init__(self, start_protected_value=0):
        self.protected_value = start_protected_value
    # 
    @property
    def protected_value(self):
        return self._protected_value
    #
    @protected_value.setter
    def protected_value(self, value):
        if value != int(value):
            raise TypeError("protected_value must be an integer")
        if 0 <= value <= 100:
            self._protected_value = int(value)
        else:
            raise ValueError("protected_value must be " +
                             "between 0 and 100 inclusive")
    #
    @protected_value.deleter
    def protected_value(self):
        raise AttributeError("do not delete, protected_value can be set to 0")

(Note that __init__ refers to self.protected_value but the property methods refer to self._protected_value. This is so that __init__ uses the property through the public API, ensuring it is "protected".)

And usage:

>>> p1 = Protective(3)
>>> p1.protected_value
3
>>> p1 = Protective(5.0)
>>> p1.protected_value
5
>>> p2 = Protective(-5)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in __init__
  File "<stdin>", line 15, in protected_value
ValueError: protectected_value must be between 0 and 100 inclusive
>>> p1.protected_value = 7.3
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 17, in protected_value
TypeError: protected_value must be an integer
>>> p1.protected_value = 101
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 15, in protected_value
ValueError: protectected_value must be between 0 and 100 inclusive
>>> del p1.protected_value
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 18, in protected_value
AttributeError: do not delete, protected_value can be set to 0

Do the names matter?

Yes they do. .setter and .deleter make copies of the original property. This allows subclasses to properly modify behavior without altering the behavior in the parent.

class Obj:
    """property demo"""
    #
    @property
    def get_only(self):
        return self._attribute
    #
    @get_only.setter
    def get_or_set(self, value):
        self._attribute = value
    #
    @get_or_set.deleter
    def get_set_or_delete(self):
        del self._attribute

Now for this to work, you have to use the respective names:

obj = Obj()
# obj.get_only = 'value' # would error
obj.get_or_set = 'value'  
obj.get_set_or_delete = 'new value'
the_value = obj.get_only
del obj.get_set_or_delete
# del obj.get_or_set # would error

I'm not sure where this would be useful, but the use-case is if you want a get, set, and/or delete-only property. Probably best to stick to semantically same property having the same name.

Conclusion

Start with simple attributes.

If you later need functionality around the setting, getting, and deleting, you can add it with the property decorator.

Avoid functions named set_... and get_... - that's what properties are for.

🌐
Real Python
realpython.com › python-getter-setter
Getters and Setters: Manage Attributes in Python – Real Python
January 20, 2025 - In this example, the constructor of Label takes two arguments, text and font. These arguments are stored in the ._text and ._font non-public instance attributes, respectively. Then you define getter and setter methods for both attributes.
🌐
GeeksforGeeks
geeksforgeeks.org › python › encapsulation-in-python
Encapsulation in Python - GeeksforGeeks
Update data using a setter method with optional validation or restrictions. Example: This example shows how to use a getter and a setter method to safely access and update a private attribute (__salary).
Published   2 weeks ago
🌐
Javatpoint
javatpoint.com › getter-and-setter-in-python
Getter and Setter in Python - Javatpoint
Getter and Setter in Python with python, tutorial, tkinter, button, overview, entry, checkbutton, canvas, frame, environment set-up, first python program, operators, etc.
Find elsewhere
🌐
Programiz
programiz.com › python-programming › property
Python @property Decorator (With Examples)
A pythonic way to deal with the above problem is to use the property class. Here is how we can update our code: # using property class class Celsius: def __init__(self, temperature=0): self.temperature = temperature def to_fahrenheit(self): return (self.temperature * 1.8) + 32 # getter def get_temperature(self): print("Getting value...") return self._temperature # setter def set_temperature(self, value): print("Setting value...") if value < -273.15: raise ValueError("Temperature below -273.15 is not possible") self._temperature = value # creating a property object temperature = property(get_temperature, set_temperature)
🌐
Medium
medium.com › @imshivam077 › day-32-getters-and-setters-f3747f62491e
Day-32 — Getters And Setters. In Python, getters and setters are… | by Shivam Shukla | Medium
December 20, 2023 - Here is an example of a class with both getter and setter: class MyClass: def __init__(self, value): self._value = value @property def value(self): return self._value @value.setter def value(self, new_value): self._value = new_value ...
Top answer
1 of 5
11
tl;dr - getters and setters are used so that people creating classes can upgrade classes without breaking the code of those that use them. Getters and setters wrap attributes as methods, allowing you to use functionality only available through methods. In Python, we don’t use getters and setters because we have properties, which allow us to make attributes look like methods after the fact. —- To really understand getters and setters means understanding class design, understanding the potential problems with accessing object attributes, understanding why some languages use getters and setters, and finally understanding why we do not need getters and setters in Python. Imagine designing a class, but for a library, a library that people other than you will use. You might design a class once and then you are done with it, but in all likelihood you’ll want to design it in a way where you can upgrade the functionality of it if you need to, so you need to design it in a futureproof way. The most important thing here is to ensure that, when you do upgrade your class with new functionality, you do it in a way that does not break the code of the people that are using it. This is the concept of backwards compatibility - your new class can be used by people who write code against the older class. The importance of this cannot be understated - if you continuously break people’s code every time you upgrade your own, no one will want to use your code, ever. To ensure backwards compatibility, all the things that the people who write code access in your class access must not change. This means - the library import, the class name, the method names, the method parameters, what the method returns, and the attributes of the class - all these must be unchanged. All these aspects make up what is known as the public API of your class, and changing these means breaking backwards compatibility. Now, consider writing code for such a class. For a complicated method, you may wish to refactor its code into multiple sub-methods. Or, you may need to store attributes on your class for reasons of convenience. Having these as part of your public API would be undesirable, partly because the people using your library class do not need to access these, but mostly because if they end up using them, it’ll hamper your ability to upgrade your class in the future. These end up being private methods and attribute - these are not meant to be accessible by people who use your code and you are free to change them should you need to in the future. Languages like C++ and Java let you label functions and attributes as public and private, and people using your library class will be barred from accessing private elements. In Python, there is no public or private - instead you name your private elements giving it a prefix of a single underscore (i.e. self._bar instead of self.bar), and whilst calling code can access these underscore variables, they understand that they generally must not unless they absolutely have to. An important part of protecting your public API is also related to attributes. Attribute access is very limited - you can get a value from an attribute, set a value onto an attribute, and delete an attribute entirely (get, set and delete) - and that’s about it. The problem is, when you upgrade your class, you may end to wanting to do something more. For example, you may want to add validation - i.e. you may want to raise an exception if someone assigns an incorrect value to an attribute. Or you might want to change one attribute to retrieve data from another place - a classic example is a class that provides temperature for something in both Celsius and Fahrenheit, the attribute for one should just get the attribute for the other and then do the C-to/from-F conversion. These are things that can be done only by methods, not attributes, and if you use an attribute as part of your public API you can’t upgrade your class to use these things without breaking the code of those that use your class, because they are accessing an attribute (self.bar) rather than a method (self.bar()). This is where getters and setters come into play. Languages like Java and C++ use these. The concept is simple - have your attributes as private (i.e. self._bar), and then wrap your private attributes in public methods. This is how it looks in Python: def get_bar(self): return self._bar def set_bar(self, val): self._bar = val The people that use your code then use self.get_bar() and self.set_bar() when interacting with your class. Because they are interacting with a method, you can upgrade your class with the above functionality described, without breaking your public API. Getters and setters solve an important problem, but they are not without problems - the biggest being that they are fugly. The people that use your code have to do self.get_bar() rather than self.bar. But the bigger problem is for you, the creator of the class, who has to litter your code with getters and setters, regardless of whether you need them or not. You may never need to upgrade your class in the future, but you’ll need to use getters and setters if you want to expose an attribute, just on the off chance you’ll need it. Python solves this problem with properties. Properties allow for attributes to be converted into methods, but still be accessed as attributes. You, as the creator of a class, use public attributes when required (self.bar). When you upgrade your class, if and only if you need the functionality of a method, you use a property. You convert your public attribute into a private one (self._bar) and then you use the below syntax: @property def bar(self): return self._bar @bar.setter def bar(self, val): self._bar = val People who call your code still access the same way as an attribute (self.bar) but you now have a method under the hood, so you can use functionality that only methods can do, without breaking your public API for your users. And you only add properties when you need them, so you don’t litter your code like you would with getters and setters.
2 of 5
7
Generally an object doesn't want you directly accessing or changing it's attributes. This is kinda the point of encapsulation. As such, you generally want to have 'getters' (that GET an objects attributes) and 'setters' (that, as you may guess, SET those attributes.) Say you have a Ball class. Ball has an attribute, diameter. Let's now say softball is an instance of object Ball. You COULD use softball.diameter to access this attribute. In programming it's generally frowned upon, though in Python less so. You might have an object method, say, get_diameter() that returns the diameter. So instead of accessing the variable directly through softball.diameter, you use ball.get_diameter() which is an example of a getter. See if you can imagine how a setter would look. This allows you to encapsulate how attributes are set, changed, accessed, etc, inside the method itself, and is generally considered a good thing.
🌐
TutorialsPoint
tutorialspoint.com › What-are-Getters-Setters-methods-for-Python-Class
Getters and Setters Methods for Python Class
May 29, 2025 - class Sum: def __init__(self, var1, var2): self._var1 = var1 self._var2 = var2 print("Sum:", self._var1 + self._var2) # Getter for var1 def get_var1(self): return self._var1 # Setter for var1 def set_var1(self, value): self._var1 = value # Properly update the attribute # Create object obj1 = Sum(15, 78) # Get value using getter print("Getter method:", obj1.get_var1()) # Set new value using setter obj1.set_var1(100) # Verify the change print("Updated value after setter:", obj1.get_var1()) ... In Python, property() is a built-in function that allows you to create properties with getter and setter behavior.
🌐
TutorialsPoint
tutorialspoint.com › getter-and-setter-in-python
Getter and Setter in Python
January 2, 2020 - class year_graduated: def __init__(self, year=0): self._year = year # getter method def get_year(self): return self._year # setter method def set_year(self, a): self._year = a grad_obj = year_graduated() # Before using setter print(grad_obj...
🌐
Analytics Vidhya
analyticsvidhya.com › home › getter and setter in python
Getter and Setter in Python - Analytics Vidhya
February 17, 2024 - Python provides a built-in property decorator that allows us to define getters and setters concisely and elegantly. The property decorator converts a method into a read-only attribute, and we can define a setter method using the same decorator. class Person: def __init__(self, name): self._name = name @property def name(self): return self._name @name.setter def name(self, value): self._name = value · The above example defines a `Person` class with a private attribute _name.
🌐
GeeksforGeeks
geeksforgeeks.org › python › python-property-function
Python property() function - GeeksforGeeks
July 11, 2025 - Creating an instance with "Peter" triggers the getter on print(x.value), setting "Diesel" calls the setter and del x.value invokes the deleter. Understanding the difference between properties and attributes in Python is important for writing ...
🌐
GeeksforGeeks
geeksforgeeks.org › python › python-property-decorator-property
Python Property Decorator - @property - GeeksforGeeks
July 12, 2025 - # Python program to illustrate the use of # @property decorator # Defining class class Portal: # Defining __init__ method def __init__(self): self.__name ='' # Using @property decorator @property # Getter method def name(self): return self.__name # Setter method @name.setter def name(self, val): self.__name = val # Deleter method @name.deleter def name(self): del self.__name # Creating object p = Portal(); # Setting name p.name = 'GeeksforGeeks' # Prints name print (p.name) # Deletes name del p.name # As name is deleted above this # will throw an error print (p.name)
🌐
Medium
medium.com › @pranaygore › setters-and-getters-in-python-76b5473b3c83
Setters and Getters in Python. A getter is a method that gets the… | by Pranay Gore | Medium
April 21, 2020 - Setters and Getters in Python A getter is a method that gets the value of a property. In OOPs this helps to access private attributes from a class. A setter is a method that sets the value of a …
🌐
Eli Bendersky
eli.thegreenplace.net › 2009 › 02 › 06 › getters-and-setters-in-python
Getters and setters in Python - Eli Bendersky's website
But in languages like Python it's unnecessary! You can just begin with a plain attribute, letting clients access it. If, at some point, a need will arise to hide the attribute from direct access, no problem, just use the property function. The canonical example is degrees and radians.
🌐
Llego
llego.dev › home › blog › python getter and setter methods: a comprehensive guide
Python Getter and Setter Methods: A Comprehensive Guide - llego.dev
July 17, 2023 - This comprehensive guide will explain what getter and setter methods are, why they are used, how to implement them in Python, and provide examples demonstrating their usage. Best practices for designing getter and setter methods will also be covered.