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
🌐
Python documentation
docs.python.org › 3 › library › functions.html
Built-in Functions — Python 3.14.3 documentation
2 weeks ago - The @property decorator turns the voltage() method into a “getter” for a read-only attribute with the same name, and it sets the docstring for voltage to “Get the current voltage.”
🌐
Programiz
programiz.com › python-programming › property
Python @property Decorator (With Examples)
Let's look at how to implement this as a decorator: class Celsius: def __init__(self, temperature=0): # when creating the object, the setter method is called automatically self.temperature = temperature def to_fahrenheit(self): # convert the temperature to Fahrenheit return (self.temperature * 1.8) + 32 @property def temperature(self): print("Getting value...") return self._temperature @temperature.setter def temperature(self, value): print("Setting value...") # ensure the temperature does not go below absolute zero if value < -273.15: raise ValueError("Temperature below -273.15°C is not poss
Discussions

Confused about decorators, classmethod and staticmethod
I recommend having a look at the Pythons class development YouTube lecture by Raymond Hettinger who is a Python core developer. The talk is old and is about Python 2 but can be easily adapted to Python 3. In essence most methods are instance methods and are designed to access instance data: class CustomClass(object): def __init__(x, y): self.x = x self.y = y def x_squared(self): return self.x ** 2 self essentially means "this instance" and so: this_instance = CustomClass(3, 4) When the method is called from the class, an instance needs to be supplied: CustomClass.x_squared(self=this_instance) The method can then work on the instance data. Normally self is provided positionally. When a method is called from an instance, the instance is implied: this_instance.x_squared() And therefore the instance data from this_instance will be used. The main use of a class method is an alternative constructor: class CustomClass(object): def __init__(x, y): self.x = x self.y = y @classmethod def from_inverse(cls, a, b): x = 1 / a y = 1 / b return CustomClass(x, y) This means a new CustomClass can be created using: this_instance = CustomClass(x=3, y=4) Or the alternative constructor: that_instance = CustomClass.from_inverse(a=1/3, b=1/3) Notice that the class method is called from the class and does not have an instance. The class method can be called from an instance although it is not common to do so: that_instance = this_instance.from_inverse(a=1/3, b=1/3) However all it does is determine the type of the class from the instance and invoke the class method and does not access instance data. Examples of this are in the datetime class (in the datetime module) which has from_isoformat, from_isocalendar, from_ordinal and from_timestamp which each act as alternative constructors for the datetime class from differing input formats. Notice most the alternative constructors have from in the method name. now is also an alternative constructor, constructing a datetime instance from the system clock. The final method, the static method is neither bound to a class or a method. It is far less commonly used. The static method is a regular function found in the namespace of a class and is only placed there for convenience. Notice that it neither has self (an instance) or cls (a class) as the first input argument and is therefore not bound to an instance or a class: class CustomClass(object): def __init__(x, y): self.x = x self.y = y @staticmethod def some_function(c, d): return c + d The video tutorial by Raymond Hettinger will give you a better understanding. More on reddit.com
🌐 r/learnpython
10
8
December 24, 2023
Why does Python @property decorator take 4 arguments if we only pass it 1?
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
5
1
July 3, 2023
Overriding the decorator of an abstract class in the inherited class
The reason why it's not being overridden is that @decorator is being evaluated at class definition. Python constructs the class top to bottom, and the class doesn't even exist until the very end. You're expecting @decorator to pull decorator from the current class (possibly subclass) but there are no classes yet when this line of code is reached, Python is still creating the DataWrapper class. Here's a short example: class DataWrapper(object): data = 1 other = DataWrapper.data # NameError: name 'DataWrapper' is not defined DataWrapper doesn't exist until the very end of the class definition (how could it, you are still defining it!) So the @decorator in your code is NOT referencing Datawrapper.decorator (or your intention, .decorator) it is referencing the name in the local namespace right above it. Like this: class DataWrapper(object): data = 1 other = data class DataManipulation(DataWrapper): data = 2 print DataManipulation().other # 1 or 2? Note how other is being set directly in DataWrapper to 1, and even though you re-define data in DataManipulation, the definition of other has already occurred during the creation of DataWrapper Put another way, this class DataWrapper(object): def decorator(...): ... @decorator def method(...): ... Is much more similar to this def decorator(...): ... @decorator def method(...): ... or even def decorator(...): ... class DataWrapper(object): @decorator def method(...): ... This doesn't answer your question but hopefully explains why your current approach didn't work. More on reddit.com
🌐 r/learnpython
6
1
November 20, 2014
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
9
May 26, 2023
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)
🌐
Python 101
python101.pythonlibrary.org › chapter25_decorators.html
Chapter 25 - Decorators — Python 101 1.0 documentation
If you look at the signature for property, it has fget, fset, fdel and doc as “arguments”. You can create another decorated method using the same name to correspond to a delete function using @fee.deleter if you want to catch the del command against the attribute. At this point you should know how to create your own decorators and how to use a few of Python...
🌐
GeeksforGeeks
geeksforgeeks.org › python › python-property-decorator-property
Python Property Decorator - @property - GeeksforGeeks
July 12, 2025 - Which is used to return the property attributes of a class from the stated getter, setter and deleter as parameters. Now, lets see some examples to illustrate the use of @property decorator in Python: Example 1:
🌐
Python Basics
python-basics-tutorial.readthedocs.io › en › latest › oop › property.html
@property decorator - Python Basics
In both cases, getter and setter methods would do the job, but at the cost of losing easy access to instance variables in Python. The answer is to use a property. This combines the ability to pass access to an instance variable via methods such as getters and setters with simple access to instance variables via dot notation. To create a property, the property decorator is used with a method that has the name of the property:
🌐
freeCodeCamp
freecodecamp.org › news › python-property-decorator
The @property Decorator in Python: Its Use Cases, Advantages, and Syntax
December 19, 2019 - Properties can be considered the "Pythonic" way of working with attributes because: The syntax used to define properties is very concise and readable. You can access instance attributes exactly as if they were public attributes while using the "magic" of intermediaries (getters and setters) to validate new values and to avoid accessing or modifying the data directly. By using @property, you can "reuse" the name of a property to avoid creating new names for the getters, setters, and deleters.
Find elsewhere
🌐
Python Reference
python-reference.readthedocs.io › en › latest › docs › functions › property.html
property — Python Reference (The Right Way) 0.1 documentation
Property decorator allows a class’ attribute to be managed, validated, proxied, secured, or protected in any other way from direct access.
🌐
Tutorial Teacher
tutorialsteacher.com › python › property-decorator
Python: Property Decorator @property
You can use the following three decorators to define a property: ... @<property-name>.setter: Specifies the setter method for a property that sets the value to a property. @<property-name>.deleter: Specifies the delete method as a property that deletes a property. The following declares the method as a property. This method must return the value of the property.
🌐
Python Tutorial
pythontutorial.net › home › python oop › python property decorator
Python Property Decorator
March 31, 2025 - class MyClass: def __init__(self, attr): self.prop = attr @property def prop(self): return self.__attr @prop.setter def prop(self, value): self.__attr = valueCode language: Python (python) In this pattern, the __attr is the private attribute and prop is the property name. The following example uses the @property decorators to create the name and age properties in the Person class:
🌐
Real Python
realpython.com › python-property
Python's property(): Add Managed Attributes to Your Classes – Real Python
December 15, 2024 - A property in Python is a tool for creating managed attributes in classes. The @property decorator allows you to define getter, setter, and deleter methods for attributes.
🌐
StrataScratch
stratascratch.com › blog › how-to-use-python-property-decorator-with-examples
How to Use Python Property Decorator (With Examples) - StrataScratch
November 16, 2023 - In this code, the Python property decorator makes it so that you can't just randomly set the temperature to any value. It has to be between 10 and 40 for the model to work properly.
🌐
LinkedIn
linkedin.com › pulse › understanding-property-decorator-python-nuno-bispo-m7aee
Understanding the @property Decorator in Python
February 7, 2024 - The @property decorator in Python makes implementing read-only attributes straightforward and elegant. A read-only property is created by defining a method in a class and applying the @property decorator, without adding a setter for that property.
🌐
Medium
medium.com › @dillonf2 › a-beginners-guide-to-python-s-property-decorator-ee01807cfdb1
A Beginner’s Guide to Python’s @property Decorator | by Frank Dillon | Medium
September 18, 2023 - In Python, @property is a built-in tool that helps you control how you access and modify attributes in a class. Think of it as a way to make your code neater and more straightforward.
🌐
WsCube Tech
wscubetech.com › resources › python › property
Property in Python: Method and Decorator Explained
October 1, 2025 - Learn about Python @property decorator with examples, methods, and more. Simplify getter and setter methods in Python classes using this powerful feature.
🌐
AlgoMaster
algomaster.io › learn › python › property-decorator
Property Decorator | Python | AlgoMaster.io | AlgoMaster.io
January 3, 2026 - The @property decorator is a built-in feature in Python that allows you to define a method as a property.
🌐
Programiz
programiz.com › python-programming › methods › built-in › property
Python property()
Instead of using property(), you can use the Python decorator @property to assign the getter, setter, and deleter.
🌐
The Teclado Blog
blog.teclado.com › property-decorator-in-python
The @property decorator in Python - The Teclado Blog
January 26, 2023 - The property decorator allows us to define methods that act as attributes in Python classes. This simplifies using the objects, and extends what we can do when getting and setting attribute values.
🌐
AskPython
askpython.com › home › how to use python property decorator?
How to Use Python Property Decorator? - AskPython
June 21, 2021 - The Property decorator is based on the in-built property() function. This function returns a special property object. You can call this in your Python Interpreter and take a look:
🌐
Medium
neuralpai.medium.com › understanding-python-property-decorators-getters-setters-57d6b535e5d2
Understanding Python Property Decorators: Getters, Setters | by Nishant Gupta | Medium
February 23, 2025 - The property decorator in Python is a powerful feature that allows you to define “getter”, “setter” methods for class attributes without explicitly calling them as methods.