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__)
Answer from Martijn Pieters on Stack Overflow
Top answer
1 of 15
1350

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)
🌐
StrataScratch
stratascratch.com › blog › how-to-use-python-property-decorator-with-examples
How to Use Python Property Decorator (With Examples) - StrataScratch
November 16, 2023 - Used the Python property decorator for undergoing_treatment to get the status. Employed @undergoing_treatment.deleter to specify the conditions under which the attribute can be deleted. In this example, the deletion is conditioned on whether the patient is undergoing treatment.
Discussions

Python decorator for attribute and method? - Stack Overflow
Is it possible to have a decorator that makes a method work like an attribute if values are assigned to it using class.something = 2 and work like a method if it is called like class.something(2, T... More on stackoverflow.com
🌐 stackoverflow.com
May 8, 2014
What is the @property decorator meant to be used for?
As people have stated the @property decorator makes a method accessible as if it was an attribute. While this can be used for validation it seems to be more commonly used for backwards compatibility. You may write a class that uses attributes and then later need to turn that code into a function, to do validation, or do some computation. The problem is you and anyone using your code may have Class.mything = 'something' throughout their code. If you try to change mything to a method that code is going to break. This is one of the reasons why getters and setters are used in other languages. In python however the @property decorator lets us replace the attribute with a method without changing how it is accessed externally. More on reddit.com
🌐 r/learnpython
5
27
July 27, 2021
When not to use @property decorator?
A property looks like a field to someone who doesn't know how the class works, so it should act more or less like a field or the users of the class are going to get confused, which is bad. A few things I can think of: A property probably shouldn't have side effects (aside from setters setting values), certainly not side effects that are obvious from outside the class. Imagine you asked for the length of an array and the property's getter called print() or something. A property probably shouldn't take too long to generate. Imagine you had a large, highly connected graph that you were manipulating, and you gave it a property that returned all the shortest paths in the graph as a matrix, and it was generated each time, which took seconds or more. If x.prop == val would evaluate to False for any reason immediately after x.prop = val, then prop shouldn't be a property. More on reddit.com
🌐 r/learnpython
12
10
May 26, 2023
Using @property decorator to create attributes and to create getters and setters for said attributes
Try this: c = Color() c.color = 'red' print(c.color) Python automatically calls setter and getter for this. add a print inside the code to confirm it. More on reddit.com
🌐 r/learnpython
5
2
September 25, 2020
🌐
LabEx
labex.io › tutorials › python-how-to-implement-python-attribute-decorators-419933
How to implement Python attribute decorators | LabEx
Python attribute decorators are a powerful and flexible technique that allows developers to modify or enhance the behavior of class attributes and methods dynamically.
🌐
Tutorial Teacher
tutorialsteacher.com › python › property-decorator
Python: Property Decorator @property
class Student: def __init__(self, name): self.__name=name @property def name(self): return self.__name @name.setter #property-name.setter decorator def name(self, value): self.__name = value · Above, we have two overloads of the name() method. One is for the getter and another is the setter method. The setter method must have the value argument that can be used to assign to the underlying private attribute.
🌐
The Teclado Blog
blog.teclado.com › property-decorator-in-python
The @property decorator in Python - The Teclado Blog
May 12, 2022 - If you are unfamiliar with what an "object" is, check out this article for a quick review. For example, if you have a class called Human, an attribute would be any variable that exists on each object of that class.
🌐
LinkedIn
linkedin.com › pulse › understanding-property-decorator-python-nuno-bispo-m7aee
Understanding the @property Decorator in Python
February 7, 2024 - In this example, temperature acts as a property. Accessing c.temperature triggers the getter method, which simply returns the internal _temperature value, while setting c.temperature triggers the setter method, which includes a validation check. This encapsulates the internal representation (_temperature) and allows for additional logic (like validation) to be executed during attribute access. The @property decorator in Python makes implementing read-only attributes straightforward and elegant.
Find elsewhere
🌐
Medium
medium.com › techtofreedom › understand-the-property-decorator-of-python-classes-a6e75011cde2
Understand the Property Decorator of Python Classes | by Yang Zhou | TechToFreedom | Medium
June 13, 2020 - Understand the Property Decorator of Python Classes Introduction In object-oriented programming, each attribute of a class may have three basic methods: A getter method to get its value A setter …
🌐
freeCodeCamp
freecodecamp.org › news › python-property-decorator
The @property Decorator in Python: Its Use Cases, Advantages, and Syntax
December 19, 2019 - The @property is a built-in decorator for the property() function in Python. It is used to give "special" functionality to certain methods to make them act as getters, setters, or deleters when we define properties in a class. Now that you are familiar with decorators, let's see a real scenario of the use of @property! Let's say that this class is part of your program. You are modeling a house with a House class (at the moment, the class only has a price instance attribute defined):
🌐
Real Python
realpython.com › python-property
Python's property(): Add Managed Attributes to Your Classes – Real Python
April 17, 2026 - Circle now is more Pythonic and clean. You don’t need to use method names such as ._get_radius(), ._set_radius(), and ._del_radius() anymore. Now you have three methods with the same descriptive attribute-like name. How’s that possible? The decorator approach for creating properties requires defining a first method using the public name for the underlying managed attribute, which is .radius in this example.
🌐
Python Tutorial
pythontutorial.net › home › python oop › python property decorator
Python Property Decorator
March 31, 2025 - class Person: def __init__(self, ... ValueError('The name cannot be empty') self._name = valueCode language: Python (python) Use the @property decorator to create a property for a class....
🌐
Python 101
python101.pythonlibrary.org › chapter25_decorators.html
Chapter 25 - Decorators — Python 101 1.0 documentation
There are also decorators in various parts of Python’s standard library. One example would be functools.wraps.
🌐
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.
🌐
Medium
medium.com › @christopher.kelly1997 › python-decorators-and-dynamic-properties-55402a2e1aff
Python Decorators and Dynamic Properties | by Christopher Hugh Kelly | Medium
April 23, 2025 - Also the _ denotes a private attribute here in Python. That is also why you need the _ in the set too. So you don’t accidentally overwrite the property and cause access hell. We call the one with the _ in front of the name the private name. The one without is the public name. ... One other thing to note about the property method that you do not see here, technically the property decorator applies the access restrictions to a class attribute that is accessed via an object.
🌐
Scaler
scaler.com › home › topics › python @property decorator
Property Decorator in Python | @property Decorator - Scaler Topics
February 22, 2022 - It implements the same logic from example 3 but with the property() method instead. ... Each attribute can have its property attribute. As an exercise, try to add a _fullname attribute and its respective getter, setter, and deleter with the property() function. If the doc argument is not mentioned, the docstring under the Getter function is used for the entire property attribute. A python decorator ...
🌐
GeeksforGeeks
geeksforgeeks.org › python › decorators-in-python
Decorators in Python - GeeksforGeeks
Example: This code demonstrates a class decorator that adds a class_name attribute to a class, storing class’s name.
Published: 3 weeks ago
🌐
AskPython
askpython.com › python › built-in-methods › python-property-decorator
How to Use Python Property Decorator? - AskPython
June 21, 2021 - You can call this in your Python Interpreter and take a look: >>> property() <property object at 0x000002BBD7302BD8> This property object has some extra methods, for getting and setting the values of the object. It also has a method for deleting it. ... But it does not stop there! These methods can be used on other objects too, and act as decorators themselves! So, for example, we can use property().getter(obj), which will give us another property object!
🌐
GeeksforGeeks
geeksforgeeks.org › python › python-property-decorator-property
Python Property Decorator - @property - GeeksforGeeks
July 12, 2025 - Where, the method name(self) labeled with @property is a getter method, name(self, val) is a setter method as it is used to set the value of the attribute __name and so its labeled with @name.setter. Lastly, the method labeled with @name.deleter is a deleter method which can delete the assigned value by the setter method. However, deleter is invoked with the help of a keyword del. Example 2: ... # Python program to illustrate the use of # @property decorator # Creating class class Celsius: # Defining init method with its parameter def __init__(self, temp = 0): self._temperature = temp # @prope
🌐
Real Python
realpython.com › primer-on-python-decorators
Primer on Python Decorators – Real Python
September 1, 2026 - Some commonly used decorators are even built-ins in Python, including @classmethod, @staticmethod, and @property. The @classmethod and @staticmethod decorators are used to define methods inside a class namespace that aren’t connected to a ...
🌐
Readthedocs
tango-controls.readthedocs.io › projects › pytango › en › stable › versions › migration › to-9.4 › attr-decorators.html
New attribute decorators — PyTango 10.3.1 documentation
from tango import AttReqType, DevState from tango.server import Device, attribute class Test(Device): _simulated_voltage = 0.0 voltage = attribute(dtype=float) @voltage.getter def voltage(self): return self._simulated_voltage @voltage.setter def voltage(self, value): self._simulated_voltage = value @voltage.is_allowed def voltage_can_be_changed(self, req_type): if req_type == AttReqType.WRITE_REQ: return self.get_state() == DevState.ON else: return True · There are many variations possible when using these. See more in Writing TANGO servers in Python.