Свойства (@property) объектов

Введение

Примеры

  • Использование декоратора @property

    @property декоратор может быть использован для определения методов в классе , которые действуют как атрибуты. Одним из примеров, где это может быть полезно, является предоставление информации, которая может потребовать первоначального (дорогостоящего) поиска и простого поиска после этого.

    Учитывая некоторый модуль foobar.py :

     class Foo(object):
        def __init__(self):
            self.__bar = None
    
        @property
        def bar(self):
            if self.__bar is None:
                self.__bar = some_expensive_lookup_operation()
            return self.__bar 

    затем

     >>> from foobar import Foo
    >>> foo = Foo()
    >>> print(foo.bar)  # This will take some time since bar is None after initialization
    42
    >>> print(foo.bar)  # This is much faster since bar has a value now
    42 
  • Использование декоратора @property для свойств чтения-записи

    Если вы хотите использовать @property для реализации пользовательского поведения для установки и получения, использовать этот шаблон:

     class Cash(object):
        def __init__(self, value):
            self.value = value
        @property
        def formatted(self):
            return '${:.2f}'.format(self.value)
        @formatted.setter
        def formatted(self, new):
            self.value = float(new[1:])
    
     

    Чтобы использовать это:

     >>> wallet = Cash(2.50)
    >>> print(wallet.formatted)
    $2.50
    >>> print(wallet.value)
    2.5
    >>> wallet.formatted = '$123.45'
    >>> print(wallet.formatted)
    $123.45
    >>> print(wallet.value)
    123.45 
  • Переопределение только метода получения, установки или удаления объекта свойства

    При наследовании от класса со свойством, вы можете предоставить новую реализацию одного или несколько свойства getter , setter или deleter функций, с помощью ссылки на объекте собственности на родительском классе:

     class BaseClass(object):
        @property
        def foo(self):
            return some_calculated_value()
    
        @foo.setter
        def foo(self, value):
            do_something_with_value(value)
    
    
    class DerivedClass(BaseClass):
        @BaseClass.foo.setter
        def foo(self, value):
            do_something_different_with_value(value)
    
     

    Вы также можете добавить установщик или удалитель, если раньше его не было в базовом классе.

  • Использование свойств без декораторов

    Хотя использование синтаксиса декоратора (с @) удобно, оно также немного скрыто. Вы можете использовать свойства напрямую, без декораторов. Следующий пример Python 3.x показывает это:

    class A:
        p = 1234
        def getX (self):
            return self._x
    
        def setX (self, value):
            self._x = value
    
        def getY (self):
            return self._y
    
        def setY (self, value):
            self._y = 1000 + value    # Weird but possible
    
        def getY2 (self):
            return self._y
    
        def setY2 (self, value):
            self._y = value
    
        def getT    (self):
            return self._t
    
        def setT (self, value):
            self._t = value
    
        def getU (self):
            return self._u + 10000
    
        def setU (self, value):
            self._u = value - 5000
    
        x, y, y2 = property (getX, setX), property (getY, setY), property (getY2, setY2)
        t = property (getT, setT)
        u = property (getU, setU)
    
    A.q = 5678
    
    class B:
        def getZ (self):
            return self.z_
    
        def setZ (self, value):
            self.z_ = value
    
        z = property (getZ, setZ)
    
    class C:
        def __init__ (self):
            self.offset = 1234
    
        def getW (self):
            return self.w_ + self.offset
    
        def setW (self, value):
            self.w_ = value - self.offset
    
        w = property (getW, setW)
    
    a1 = A ()
    a2 = A ()
    
    a1.y2 = 1000
    a2.y2 = 2000
    
    a1.x = 5
    a1.y = 6
    
    a2.x = 7
    a2.y = 8
    
    a1.t = 77
    a1.u = 88
    
    print (a1.x, a1.y, a1.y2)
    print (a2.x, a2.y, a2.y2)
    print (a1.p, a2.p, a1.q, a2.q)
    
    print (a1.t, a1.u)
    
    b = B ()
    c = C ()
    
    b.z = 100100
    c.z = 200200
    c.w = 300300
    
    print (a1.x, b.z, c.z, c.w)
    
    c.w = 400400
    c.z = 500500
    b.z = 600600
    
    print (a1.x, b.z, c.z, c.w) 

Синтаксис

Параметры

Примечания