The property object is what you are actually thinking of as a property. Consider this example:

class Foo(object):
    def __init__(self):
        self._bar = 0

    @property
    def bar(self):
        return self._bar + 5

Foo.bar is a property object which has a __get__ method. When you write something like

x = Foo()
print(x.bar)

the lookup for x.bar finds that type(x).bar has a __get__ method, and so the attribute lookup becomes equivalent to

type(x).bar.__get__(x, type(x))

which produces the value x._bar + 5.

The use of property as a decorator somewhat obscures the fact that bar is a property object. An equivalent defintion is

class Foo(object):
     def __init__(self):
         self._bar = 0

     bar = property(lambda self: self._bar + 5)

which shows more explicitly that you are creating a property object with the given lambda expression as the getter for that property, and binding the object to the class attribute bar.

The property class (along with instance methods, class methods, and static methods) is a specific application of Python's general descriptor protocol, which defines the behavior of class attributes with __get__, __set__, and/or __del__ methods.

Answer from chepner on Stack Overflow
Top answer
1 of 3
25

The property object is what you are actually thinking of as a property. Consider this example:

class Foo(object):
    def __init__(self):
        self._bar = 0

    @property
    def bar(self):
        return self._bar + 5

Foo.bar is a property object which has a __get__ method. When you write something like

x = Foo()
print(x.bar)

the lookup for x.bar finds that type(x).bar has a __get__ method, and so the attribute lookup becomes equivalent to

type(x).bar.__get__(x, type(x))

which produces the value x._bar + 5.

The use of property as a decorator somewhat obscures the fact that bar is a property object. An equivalent defintion is

class Foo(object):
     def __init__(self):
         self._bar = 0

     bar = property(lambda self: self._bar + 5)

which shows more explicitly that you are creating a property object with the given lambda expression as the getter for that property, and binding the object to the class attribute bar.

The property class (along with instance methods, class methods, and static methods) is a specific application of Python's general descriptor protocol, which defines the behavior of class attributes with __get__, __set__, and/or __del__ methods.

2 of 3
6
class MyClass:
    def __init__(self,*costs):
        self.costs = costs
    def item_cost(self):
        return sum(self.costs)

now you can do

MyClass(1,2,3,4).item_cost() #prints 10

but we can make it a property

class MyClass:
    def __init__(self,*costs):
        self.costs = costs
    @property
    def item_cost(self):
        return sum(self.costs)

and now we can access it as a simple variable

MyClass(1,2,3,4).item_cost

you could also create a setter for the value with

  ...
   @item_cost.setter
   def set_item_cost(self,value):
         pass #do something with value
  ...
 MyClass(1,2,3,4).item_cost = "yellow"

In general I find them to be sort of an anti-pattern... but some folks like em

(side note you could also make it a property using it as a regular function instead of a decorator MyClass.item_cost_prop = property(MyClass.item_cost) )

🌐
Real Python
realpython.com › python-property
Python's property(): Add Managed Attributes to Your Classes – Real Python
December 15, 2024 - If you access the managed attribute with something like obj.attr, then Python automatically calls fget(). If you assign a new value to the attribute with something like obj.attr = value, then Python calls fset() using the input value as an argument. Finally, if you run a del obj.attr statement, then Python automatically calls fdel(). Note: The first three arguments to property() take function objects.
🌐
The Python Coding Stack
thepythoncodingstack.com › p › the-properties-of-python-property
The Properties of Python's `property`
April 1, 2025 - Traceback (most recent call last): File "...", line 89, in <module> mj.athlete_id = 258762612 ^^^^^^^^^^^^^ AttributeError: property 'athlete_id' of 'ClubMember' object has no setter · The property .athlete_id is a read-only attribute. You can access its value, but you can't change it. Note that, as mentioned earlier, Python doesn't have private attributes.
🌐
GeeksforGeeks
geeksforgeeks.org › python › python-property-function
Python property() function - GeeksforGeeks
July 11, 2025 - property() function in Python is a built-in function that returns an object of the property class. It allows developers to create properties within a class, providing a way to control access to an attribute by defining getter, setter and deleter ...
🌐
Programiz
programiz.com › python-programming › property
Python @property Decorator (With Examples)
Note: The actual temperature value is stored in the private _temperature variable. The temperature attribute is a property object which provides an interface to this private variable. In Python, property() is a built-in function that creates and returns a property object.
🌐
W3Schools
w3schools.com › python › python_class_properties.asp
Python Class Properties
Python Examples Python Compiler ... Q&A Python Bootcamp Python Certificate Python Training ... Properties are variables that belong to a class. They store data for each object created from the class....
🌐
Mimo
mimo.org › glossary › python › property
Python property(): Syntax, Usage, and Examples
The property() built-in function in Python lets you manage how class attributes are accessed and modified. Instead of calling explicit getter method or setter method, you can create attributes that behave like regular variables but include custom logic behind the scenes.
🌐
Tutorial Teacher
tutorialsteacher.com › python › property-function
Python property() Method
It encapsulates instance attributes and provides a property, same as Java and C#. The property() method takes the get, set and delete methods as arguments and returns an object of the property class.
Find elsewhere
🌐
Reddit
reddit.com › r/learnpython › what is the purpose of @property ?
r/learnpython on Reddit: What is the purpose of @property ?
November 17, 2017 -

Hi guys, I'm new to Python and I was curious if I define a class, what is the fuss with getattr, setattr and @property? I've read couple topics on stackexchange, but neither did motivate why I should use them. I mean I can define own functions to set something, and just use car.wheels to get the amount of wheels. No need to define an extra function car.getattr(wheels). What am I missing.

Top answer
1 of 5
20
Properties solve several problems. The main one is that they allow you to substitute a method call for an attribute access without changing the public API. That is important if you're dealing with large software projects where you can't break backwards compatibility. The method can contain arbitrary logic. For example, suppose that you wrote a class that stores a temperature. You initially wrote it to store temperate in Fahrenheit as a simple attribute, and you have lots of existing code that depends on that. But at some point you decide that you want it internally stored as Celsius. By using a computed property, you can change the internal representation to Celsius, while pretending to external users that it's still stored as Fahrenheit, by writing a getter method that dynamically computes the conversion. This is intentionally silly, but you can imagine more complex examples where you want to change the internal representation or other internal implementation details without affecting the public API. Another problem it solves is of validation. With a simple attribute, users can set any value. Again going back to the temperature example, someone might set the attribute to an invalid temperature. By using a setter of a property, you can intercept that attribute access and execute arbitrary logic to perform validation, raising an exception if they do something wrong. Arguably, the getting and setting in this case should have been written as methods in the first place, rather than attributes, but again you don't always have that kind of foresight, and often design decisions change and you need to make the change without breaking the API. Properties allow that.
2 of 5
2
Since a good explanation is given for properties, perhaps I can tackle getattr (and setattr by extension). Let's use your example - you have an object car with the attribute wheels. There are two ways to access this: car.wheels getattr(car, 'wheels') So why would you use the second form? Well, look at the second parameter - wheels is a string. Because the second parameter is a string, you can get attributes dynamically from an object. Imagine you wanted to have user input to allow the user to grab an attribute from car and print out that attribute. (A contrived example, I know.) You could do this: attribute = input("Type car attribute") print(getattr(car, attribute)) If the user types in wheels, then this script prints out car.wheels. But if the user types in doors, then this script prints out car.doors. I hope you can see - because we are using a string to access the object's attribute, you can do more dynamic things with this functionality.
🌐
Python Tutorial
pythontutorial.net › home › python oop › python property
Python Property
March 31, 2025 - Suppose you released the Person ... and setter method while achieving backward compatibility, you can use the property() class. The property class returns a property object......
🌐
IONOS
ionos.com › digital guide › websites › web development › python property
How to use Python property - IONOS
July 20, 2023 - The following code snippet creates ... Python properties are. class dog: def __init__(self): self._name = "Bello"Python · You may have noticed that the constructor doesn’t have a parameter specifying the dog’s name. Instead, the default value for the dog’s name has been set to “Bello”. In this case, you can create an object of the class ...
🌐
Machine Learning Plus
machinelearningplus.com › python › python-property
Python @Property Explained – How to Use and When? (Full Examples)
There you go. We set a new value to person.fullname, the person.first and person.last updated as well. Our Person class will now automatically update the derived attributes (property) when one of the base attribute changes and vice versa.
🌐
Real Python
realpython.com › ref › builtin-functions › property
property() | Python’s Built-in Functions – Real Python
That’s why most Python developers call it function. In practice, property() is used as a decorator most of the time. A property object that allows controlled access and mutation of an instance attribute.
Top answer
1 of 15
1343

The property() function returns a special descriptor object:

>>> property()
<property object at 0x10ff07940>

It is this object that has extra methods:

>>> property().getter
<built-in method getter of property object at 0x10ff07998>
>>> property().setter
<built-in method setter of property object at 0x10ff07940>
>>> property().deleter
<built-in method deleter of property object at 0x10ff07998>

These act as decorators too. They return a new property object:

>>> property().getter(None)
<property object at 0x10ff079f0>

that is a copy of the old object, but with one of the functions replaced.

Remember, that the @decorator syntax is just syntactic sugar; the syntax:

@property
def foo(self): return self._foo

really means the same thing as

def foo(self): return self._foo
foo = property(foo)

so foo the function is replaced by property(foo), which we saw above is a special object. Then when you use @foo.setter(), what you are doing is call that property().setter method I showed you above, which returns a new copy of the property, but this time with the setter function replaced with the decorated method.

The following sequence also creates a full-on property, by using those decorator methods.

First we create some functions:

>>> def getter(self): print('Get!')
... 
>>> def setter(self, value): print('Set to {!r}!'.format(value))
... 
>>> def deleter(self): print('Delete!')
... 

Then, we create a property object with only a getter:

>>> prop = property(getter)
>>> prop.fget is getter
True
>>> prop.fset is None
True
>>> prop.fdel is None
True

Next we use the .setter() method to add a setter:

>>> prop = prop.setter(setter)
>>> prop.fget is getter
True
>>> prop.fset is setter
True
>>> prop.fdel is None
True

Last we add a deleter with the .deleter() method:

>>> prop = prop.deleter(deleter)
>>> prop.fget is getter
True
>>> prop.fset is setter
True
>>> prop.fdel is deleter
True

Last but not least, the property object acts as a descriptor object, so it has .__get__(), .__set__() and .__delete__() methods to hook into instance attribute getting, setting and deleting:

>>> class Foo: pass
... 
>>> prop.__get__(Foo(), Foo)
Get!
>>> prop.__set__(Foo(), 'bar')
Set to 'bar'!
>>> prop.__delete__(Foo())
Delete!

The Descriptor Howto includes a pure Python sample implementation of the property() type:

class Property:
    "Emulate PyProperty_Type() in Objects/descrobject.c"

    def __init__(self, fget=None, fset=None, fdel=None, doc=None):
        self.fget = fget
        self.fset = fset
        self.fdel = fdel
        if doc is None and fget is not None:
            doc = fget.__doc__
        self.__doc__ = doc

    def __get__(self, obj, objtype=None):
        if obj is None:
            return self
        if self.fget is None:
            raise AttributeError("unreadable attribute")
        return self.fget(obj)

    def __set__(self, obj, value):
        if self.fset is None:
            raise AttributeError("can't set attribute")
        self.fset(obj, value)

    def __delete__(self, obj):
        if self.fdel is None:
            raise AttributeError("can't delete attribute")
        self.fdel(obj)

    def getter(self, fget):
        return type(self)(fget, self.fset, self.fdel, self.__doc__)

    def setter(self, fset):
        return type(self)(self.fget, fset, self.fdel, self.__doc__)

    def deleter(self, fdel):
        return type(self)(self.fget, self.fset, fdel, self.__doc__)
2 of 15
403

The documentation says it's just a shortcut for creating read-only properties. So

@property
def x(self):
    return self._x

is equivalent to

def getx(self):
    return self._x
x = property(getx)
🌐
Toppr
toppr.com › guides › python-guide › references › methods-and-functions › python-property
Python property() function: Property python, python @property
October 18, 2021 - In Python, Properties is a class for maintaining class attributes. Python property( ) is a built-in function for creating and returning a property object.
🌐
Medium
martinxpn.medium.com › properties-in-python-53-100-days-of-python-1a750ebeead5
Properties in Python (53/100 Days of Python) | by Martin Mirakyan | Medium
April 10, 2023 - Properties in Python (53/100 Days of Python) In Python, properties are a type of attribute that allow for controlled access to an object’s internal data. They are a way of defining getter and …
🌐
Mathspp
mathspp.com › blog › pydonts › properties
mathspp – take your Python 🐍 to the next level 🚀
If you want to see some examples of properties that implement attributes that depend dynamically on other attributes of an object, go check the source code for the module pathlib. You will find many such usages of @property there. For example, path.name is a property: ## datetime.py, Python 3.11 class PurePath(object): # ...
🌐
Reintech
reintech.io › blog › python-practical-uses-for-property-method-tutorial
Python: Practical Uses for the property() Method | Reintech media
January 4, 2026 - The property() method is a built-in Python descriptor that transforms class methods into managed attributes. Rather than directly exposing object attributes, properties create a controlled interface that executes custom logic during attribute ...
🌐
freeCodeCamp
freecodecamp.org › news › python-property-decorator
The @property Decorator in Python: Its Use Cases, Advantages, and Syntax
December 19, 2019 - Specifically, you can define three methods for a property: A getter - to access the value of the attribute. A setter - to set the value of the attribute. A deleter - to delete the instance attribute. Price is now "Protected" Please note that the price attribute is now considered "protected" because we added a leading underscore to its name in self._price: ... In Python, by convention, when you add a leading underscore to a name, you are telling other developers that it should not be accessed or modified directly outside of the class.
🌐
W3Schools
w3schools.com › python › gloss_python_object_modify_properties.asp
Python Modify Object Properties
Python Syntax Tutorial Class Create Class The Class __init__() Function Object Methods self Delete Object Properties Delete Object Class pass Statement