all Python 3OOPterm
@property
property
Turns a method into an attribute (the getter). @x.setter is the setter, @x.deleter the deleter. Computed attributes.
Syntax
@property
def x(self): return self._x
property(fget=None, fset=None, fdel=None)
You access it without parentheses — circle.radius, not circle.radius(). Inside the getter read a backing field with a different name (self._r), or self.radius re-triggers the same property and recurses forever. And with no setter defined, assignment raises AttributeError because the property is read-only.
Examples
class Circle:
def __init__(self, r):
self._r = r
@property
def radius(self):
return self._r
@radius.setter
def radius(self, value):
if value < 0:
raise ValueError('radius must be >= 0')
self._r = value
c = Circle(5)
print(c.radius) # → 5
c.radius = 10
print(c.radius) # → 10
class Celsius:
def __init__(self, temp):
self.temperature = temp
@property
def fahrenheit(self):
return self.temperature * 9/5 + 32
c = Celsius(100)
print(c.fahrenheit) # → 212.0
class Person:
def __init__(self, first, last):
self.first = first
self.last = last
@property
def full_name(self):
return f'{self.first} {self.last}'
@full_name.setter
def full_name(self, name):
self.first, self.last = name.split()
p = Person('John', 'Doe')
print(p.full_name) # → John Doe
p.full_name = 'Jane Smith'
print(p.first) # → Jane
class Square:
def __init__(self, side):
self._side = side
@property
def side(self):
return self._side
@side.setter
def side(self, v):
self._side = v
@property
def area(self):
return self._side ** 2
@property
def perimeter(self):
return 4 * self._side
s = Square(5)
print(s.area) # → 25
print(s.perimeter) # → 20
class BankAccount:
def __init__(self, balance):
self._balance = balance
@property
def balance(self):
return self._balance
@balance.setter
def balance(self, amount):
if amount < 0:
raise ValueError('Balance cannot be negative')
self._balance = amount
acc = BankAccount(100)
print(acc.balance) # → 100
# @property.deleter
class Profile:
def __init__(self):
self._avatar = 'default.png'
@property
def avatar(self):
return self._avatar
@avatar.deleter
def avatar(self):
self._avatar = 'default.png'
p2 = Profile()
p2._avatar = 'photo.jpg'
del p2.avatar
print(p2.avatar) # → default.png
# property как декоратор-класс
class Temperature:
def __init__(self, c=0):
self._c = c
temperature = property(lambda self: self._c,
lambda self, v: setattr(self, '_c', v))
t = Temperature(25)
print(t.temperature) # → 25
See also
Open in the full glossarydocs.python.orgReport an inaccuracy