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.
🌐
Real Python
realpython.com › python-getter-setter
Getters and Setters: Manage Attributes in Python – Real Python
January 20, 2025 - In this tutorial, you'll learn what getter and setter methods are, how Python properties are preferred over getters and setters when dealing with attribute access and mutation, and when to use getter and setter methods instead of properties in Python.
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
How do getters and setters work in Python? - Stack Overflow
I am learning getters and setters , what I understand is that they are used so that no one could change the object's attributes directly. In the example class Person: def __init__(self, name, a... More on stackoverflow.com
🌐 stackoverflow.com
Is there any reason to choose using a setter over making public variables?
On July 1st, a change to Reddit's API pricing will come into effect. Several developers of commercial third-party apps have announced that this change will compel them to shut down their apps. At least one accessibility-focused non-commercial third party app will continue to be available free of charge. If you want to express your strong disagreement with the API pricing change or with Reddit's response to the backlash, you may want to consider the following options: Limiting your involvement with Reddit, or Temporarily refraining from using Reddit Cancelling your subscription of Reddit Premium as a way to voice your protest. I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns. More on reddit.com
🌐 r/learnprogramming
25
9
March 10, 2023
what are getters and setters in python? and also @property can anyone please explain.
A class/object (e.g. User) can have multiple fields/attributes/members (e.g. first_name, last_name, login, password, email...). Normally, these fields/attributes/members behave like regular variables (or values in a dict ) - anybody can read- and modify them. But if you want to control access to these attributes in a more sophisticated fashion - e.g., do some validation, logging, unit conversion - then you implement a getter and a setter, which will execute some additional code upon reading/modifying the attribute in question. On the outside, however, it would still look like you were simply accessing e.g. user.login. More on reddit.com
🌐 r/learnpython
20
21
April 12, 2025
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.

🌐
TutorialsPoint
tutorialspoint.com › getter-and-setter-in-python
Getter and Setter in Python
January 2, 2020 - As the name suggests, getters are the methods which help access the private attributes or get the value of the private attributes and setters are the methods which help change or set the value of private attributes.
🌐
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)
🌐
W3Schools
w3schools.com › python › python_encapsulation.asp
Python Encapsulation
To access a private property, you ... Person("Tobias", 25) print(p1.get_age()) Try it Yourself » · To modify a private property, you can create a setter method....
🌐
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 - 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 property.
Find elsewhere
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.
🌐
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 ... = new_value ... In simple language, a setter in Python is a method that helps you set or change the value of a specific attribute in a class....
🌐
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.
🌐
Medium
salma-mohamed.medium.com › getters-setters-and-deleters-in-python-b8ae8fc02662
GETTERS, SETTERS AND DELETERS IN PYTHON | by Salma mohamed | Medium
September 7, 2023 - In this example, the @value.setter decorator allows you to set the value attribute using the setter method. You can add validation or perform other actions when setting the attribute.
🌐
TutorialsPoint
tutorialspoint.com › what-are-getters-setters-methods-for-python-class
What are Getters/Setters methods for Python Class?
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.
Top answer
1 of 5
2

The reason to use a getter and setter, is if you want to do something more complex than just set and attribute with foo.bar. In your case, set_age has an

isinstance(new_age, int) & new_age>0 & new_age<120

check, which is not possible to do with a raw attribute. (Side-note: you should use and instead of &.)

Yes, someone can still do p1._age = -1, and then their code won't work, but why would they? It just makes their code not work.

Your get_name function is less useful than the age one. It basically makes name read-only, which might or might not be useful.

When creating setters and getters in Python, it is usual to use the @property decorator. This means the functions can be called as if they were attributes, so instead of p1.get_name() you can just do p1.name. Similarly p1.set_age(3) becomes p1.age = 3.

You probably want to use the age setter in __init__, because then the age of the Person is validated when it is created.

Here is a version that makes these changes (and a couple of other readability improvements).

class Person:
    def __init__(self, name, age):
        self._name = name
        self.age = age

    @property
    def age(self):
        return self._age

    @age.setter
    def age(self, new_age):
        if isinstance(new_age, int) and 0 < new_age < 120:
            self._age = new_age
    
    @property
    def name(self):
        return self._name

    def __str__(self):
        return f"Person[{self.name}] is {self.age}"
    
p1 = Person("Sandeep", 49)
2 of 5
2

You need to tell python how to associate the getter and setter with the actual variable name. To do this you can use the builtin property function like so:

class Person
    def __init__(self, name, age):
        self._name = name
        self._age = age

    def get_age(self):
        return self._age

    def set_age(self, new_age):
        if isinstance(new_age, int) & new_age>0 & new_age<120:
            self._age = new_age

    def get_name(self):
        return self._name
    name = property(get_name)
    age = property(get_age, set_age)

    def __str__(self):
        return 'Person[' + self.name + '] is ' + str(self.age)
    
p1 = Person("Sandeep", 49)

Then instead of referring to _name and _age use name and age

🌐
Python Course
python-course.eu › oop › properties-vs-getters-and-setters.php
3. Properties vs. Getters and Setters | OOP | python-course.eu
December 2, 2023 - Let's summarize the usage of private and public attributes, getters and setters, and properties: Let's assume that we are designing a new class and we pondering about an instance or class attribute "OurAtt", which we need for the design of our class.
🌐
Scientech Easy
scientecheasy.com › home › blog › getter and setter in python
Getter and Setter in Python - Scientech Easy
October 6, 2023 - In Python, learn how to implement getter and setter method for private instance attributes in the class, advantage of using getter and setter
🌐
DataCamp
datacamp.com › tutorial › property-getters-setters
Python Property vs. Getters & Setters | DataCamp
December 18, 2018 - Getters: These are the methods used in Object-Oriented Programming (OOPS) which helps to access the private attributes from a class. Setters: These are the methods used in OOPS feature which helps to set the value to private attributes in a class. If you are not familiar with the private attributes ...
🌐
Medium
medium.com › @pijpijani › understanding-property-in-python-getters-and-setters-b65b0eee62f9
Understanding Property in Python: Getters and Setters | by Pikho | Medium
March 2, 2023 - Specifically, the setter methods check whether the input is a string and a positive integer, respectively. if the input is valid, it capitalizes the string and assigns it to name attributes. This ensures that the name and age attributes are always set to valid values, which can help prevent errors. p = Person("john", 30) print(p.name) # John print(p.age) # 30 p.age = 35 print(p.age) # 35 p.name = "rafa" print (p.name) # Rafa ... The main benefit of using getters and setters in programming is that they provide a way to control the access and modification of class attributes...
🌐
CodeRivers
coderivers.org › blog › getters-and-setters-python
Python Getters and Setters: A Comprehensive Guide - CodeRivers
February 16, 2025 - In this example, get_age is the getter method, and set_age is the setter method. The setter method validates the new age value before setting it. Python provides a property decorator that allows you to define a method as a property. This makes the method call look like an attribute access.
🌐
Codesarray
codesarray.com › view › Getters-and-Setters-in-Python
Getters and Setters in Python - Codesarray
Learn how to use getters and setters in Python to enforce data integrity, control access to attributes, and write clean, maintainable code with examples.
🌐
Python Examples
pythonexamples.org › python-class-getter-and-setter-methods
Python - Getter and Setter Methods
When circle.radius is executed, the getter method radius() is called. Now, consider the following statement. ... When this statement is executed, the setter method radius(value) is called, with 7 passed as argument for the value parameter. In this tutorial of Python Classes and Objects, we have learnt about Getter and setter methods in a class, how to use them to control how attribute values are accessed and modified in a class, with some example programs.