Note that you don't have to use property as a decorator. You can quite happily use it the old way and expose the individual methods in addition to the property:

class A:
    def get_x(self, neg=False):
        return -5 if neg else 5
    x = property(get_x)

>>> a = A()
>>> a.x
5
>>> a.get_x()
5
>>> a.get_x(True)
-5

This may or may not be a good idea depending on exactly what you're doing with it (but I'd expect to see an excellent justification in a comment if I came across this pattern in any code I was reviewing)

Answer from ncoghlan on Stack Overflow
๐ŸŒ
Real Python
realpython.com โ€บ primer-on-python-decorators
Primer on Python Decorators โ€“ Real Python
December 14, 2024 - Python decorators allow you to ... you use a Python decorator, you wrap a function with another function, which takes the original function as an argument and returns its modified version....
๐ŸŒ
Reddit
reddit.com โ€บ r/learnprogramming โ€บ why does python @property decorator take 4 arguments if we only pass it 1?
r/learnprogramming on Reddit: Why does Python @property decorator take 4 arguments if we only pass it 1?
July 2, 2023 -

In the Python docs: https://docs.python.org/3/library/functions.html#property , we see that the property method takes 4 arguments: a getter, setter, deleter, and docstring. However, in the example they provide (and other similar ones I find), we only ever seem to actually pass the getter directly into the decorator:

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

After that, we modify that property object's setters, deleters, etc:

    @x.setter
def x(self, value):
    self._x = value

Certainly I can follow and use this process, but I'm a little confused about how it's working, or why it has to be set up this way. If the property method takes in 4 arguments, why do we only ever actually pass it 1, the getter? Is it impossible to pass the property decorator the getter AND the setter AND the deleter in one go (is this a pie syntax issue)?

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)
๐ŸŒ
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
๐ŸŒ
Medium
medium.com โ€บ @christopher.kelly1997 โ€บ python-decorators-and-dynamic-properties-55402a2e1aff
Python Decorators and Dynamic Properties | by Christopher Hugh Kelly | Medium
April 23, 2025 - I have found a really great textbook ... imaginable here and is well worth the read. ... It is a first class function meaning that it takes in a function as an argument/parameter....
๐ŸŒ
Real Python
realpython.com โ€บ python-property
Python's property(): Add Managed Attributes to Your Classes โ€“ Real Python
December 15, 2024 - The @property decorator allows you to define getter, setter, and deleter methods for attributes. You use properties when you need controlled access or want to encapsulate logic without changing the API.
๐ŸŒ
FavTutor
favtutor.com โ€บ blogs โ€บ python-property-decorator
Python Property Decorator (with Examples)
November 6, 2023 - The Python property decorator is a versatile and powerful tool that provides you with the means to manage access to class attributes, introduce custom behaviors, and enhance the robustness and maintainability of your code.
Find elsewhere
๐ŸŒ
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.
๐ŸŒ
GeeksforGeeks
geeksforgeeks.org โ€บ python โ€บ python-property-decorator-property
Python Property Decorator - @property - GeeksforGeeks
July 12, 2025 - 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 # @property decorator @property # Getter method def temp(self): # Prints the assigned temperature value print("The value of the temperature is: ") return self._temperature # Setter method @temp.setter def temp(self, val): # If temperature is less than -273 than a value # error is thrown if val < -273: raise ValueError("It is a val
๐ŸŒ
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.
๐ŸŒ
GeeksforGeeks
geeksforgeeks.org โ€บ python โ€บ decorators-in-python
Decorators in Python - GeeksforGeeks
In Python, decorators are flexible ... their actual code. A decorator is essentially a function that takes another function as an argument and returns a new function with enhanced functionality....
Published ย  September 22, 2025
๐ŸŒ
Stack Abuse
stackabuse.com โ€บ the-python-property-decorator
The Python Property Decorator
September 18, 2018 - The property decorator is implemented with a pattern similar to the my_decorator function. Using the Python @decorator syntax, it receives the decorated function as an argument, just like in my example: some_func_decorated = my_decorator(some_func).
๐ŸŒ
W3Schools
w3schools.com โ€บ python โ€บ python_decorators.asp
Python Decorators
Sometimes the decorator function has no control over the arguments passed from decorated function, to solve this problem, add (*args, **kwargs) to the wrapper function, this way the wrapper function can accept any number, and any type of arguments, ...
๐ŸŒ
The Teclado Blog
blog.teclado.com โ€บ property-decorator-in-python
The @property decorator in Python
January 26, 2023 - There's the @property decorator in a nutshell! In all, it is a very powerful way to gain more control over how the attributes are set and formatted inside of your classes. By using custom getters, you can modify how you present the attributes.
๐ŸŒ
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.
๐ŸŒ
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:
๐ŸŒ
Imperial College London
python.pages.doc.ic.ac.uk โ€บ 2021 โ€บ lessons โ€บ decorator โ€บ 03-application โ€บ 03-property.html
Advanced Lesson 4: Python Decorators > Property decorator
The property class has a constructor, which takes a function (the getter method) as the first parameter, and optionally a setter method as the second parameter. Python will automatically invoke the correct methods when a user accesses the .name attribute of a VainPerson instance. If you omit the setter method (the second argument), then your property becomes a read-only property.
๐ŸŒ
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: