Python Glossary English

все Python 3ООПпонятие

@property

property

Превращает метод в атрибут (геттер). @x.setter — сеттер. @x.deleter — делитер. Вычисляемые атрибуты.

Синтаксис

@property
def x(self): return self._x
property(fget=None, fset=None, fdel=None)

Обращаются к нему без скобок — circle.radius, а не circle.radius(). Внутри геттера читайте резервное поле с другим именем (self._r): иначе self.radius снова вызовет то же свойство и уйдёт в бесконечную рекурсию. А если сеттер не описан, присваивание падает с AttributeError — свойство только для чтения.

Примеры

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

См. также

Открыть в полном глоссарииdocs.python.orgСообщить о неточности