Python property() Function
The property()
function allows to create a special type of attribute called a property
for a class.
Syntax
property(fget, fset, fdel, doc)
property() Parameters
Python property()
function parameters:
Parameter | Condition | Description |
---|---|---|
fget | Optional | A function for getting an attribute value |
fset | Optional | A function for setting an attribute value |
fdel | Optional | A function for deleting an attribute |
doc | Optional | The docstring of an attribute |
If any argument is passed as None
or omitted, that operation is not supported.
property() Return Value
Python property()
function returns:
- a property attribute from the given getter, setter, and deleter.
- a base property attribute that does not contain any getter, setter, or deleter, if no arguments are given.
Observations
attrib = property(fget, fset, fdel, doc)
creates a new class attribute called attrib
and defines the three methods as properties.
So:
- When you reference
x.attrib
, Python calls thefget
method. - When you assign
x.attrib = value
, Python calls thefset
method and passesvalue
as an argument. - When you execute del
x.attrib
, Python calls thefdel
method.
Python uses the argument you passed as doc
as the docstring of the attribute
If you do not specify the doc
parameter, the getter method’s docstring becomes the docstring of the property.
Examples
Example 1: Basic Example
class Person:
def __init__(self, name):
self._name = name
# getter function
def get_name(self):
print('Getting name')
return self._name
# setter function
def set_name(self, value):
print('Setting name to ' + value)
self._name = value
# deleter function
def del_name(self):
print('Deleting name')
del self._name
# create the property
name = property(get_name, set_name, del_name, doc='name of the person')
The get_name()
, set_name()
and del_name()
methods act like normal getter, setter and deleter until this line:
# create the property
name = property(get_name, set_name, del_name, doc='name of the person')
because it creates a new class attribute called name
and defines the three methods as its properties.
So, now, when you refer to the name
attribute of any Person
object, Python actually calls the get_name()
method:
p = Person('Ryan')
print(p.name) # Prints Getting name: Ryan
In the same way, when you assign a value to the name attribute, the set_name()
method is called.
p.name = "Tom" # Output: Setting name to Tom
print(p.name) # Output: Getting name: Tom
And when you try to delete the name attribute, the del_name()
method is called.
del p.name # Output: Deleting name
Moreover, you can access the docstring through the __doc__
attribute:
print(Person.name.__doc__) # Output: name of the person
Example 2: Computed Attributes
Properties can also be a way to define "computed attributes", i.e. attributes that are not actually stored, but are calculated dynamically on demand.
For example, let's define a class Rectangle that has a computed attribute for the area:
class Rectangle(object):
def __init__(self, width, height):
self.width = width
self.height = height
# computed attribute
def area(self):
return self.width * self.height
# make a property
area = property(area)
Then we can do:
r = Rectangle(10, 5) # Create a Rectangle object with width=10 and height=5
# and print the area
print(r.area) # Output: 50
output
50
Moreover, you can change width
and height
and the area
property will be computed accordingly:
r = Rectangle(10, 5)
print(r.area) # Output: 50
r.width = 2
print(r.area) # Output: 10
r.height = 10
print(r.area) # Output: 20
output
50
10
20
If you don't specify a setter/getter/deleter property for an attribute and you try to use that property, then you will get an AttributeError
exception.
For example:
r = Rectangle(10, 5)
r.area = 15
output
Traceback (most recent call last):
File "main.py", line 14, in <module>
r.area = 15
AttributeError: can't set attribute
Equivalent Method with @property
decorator
Instead of using property()
, a more elegant way is to use the Python decorator @property
to assign the getter, setter, and deleter.
Decorators for an attribute called attr
must be used in this way:
@property
decorator goes before the getter method@attr.setter
decorator goes before the setter method@attr.deleter
decorator goes before the deleter method
For example, the Person
class with decorators:
class Person:
def __init__(self, name):
self._name = name
# getter
@property
def name(self):
print('Getting name')
return self._name
# setter
@name.setter
def name(self, value):
print('Setting name to ' + value)
self._name = value
# deleter
@name.deleter
def name(self):
print('Deleting name')
del self._name
and so you can do:
p = Person('Tom')
# calls the getter
print('The name is:', p.name)
# calls the setter
p.name = 'Ryan'
# calls the deleter
del p.name
output
Getting name
The name is: Tom
Setting name to Ryan
Deleting name