Buscar..


Observaciones

Nota : en Python 2, asegúrese de que su clase herede del objeto (lo que lo convierte en una clase de nuevo estilo) para que todas las características de las propiedades estén disponibles.

Usando el decorador @property

El decorador de @property se puede utilizar para definir métodos en una clase que actúan como atributos. Un ejemplo en el que esto puede ser útil es cuando se expone información que puede requerir una búsqueda inicial (costosa) y una recuperación sencilla a partir de entonces.

Dado algún módulo de 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

Entonces

>>> 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

Usando el decorador de propiedad para las propiedades de lectura-escritura

Si desea usar @property para implementar un comportamiento personalizado para configurar y obtener, use este patrón:

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:])

Para usar esto:

>>> 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

Anulando solo un captador, configurador o un eliminador de un objeto de propiedad

Cuando se hereda de una clase con una propiedad, puede proporcionar una nueva aplicación para una o más de las propiedades getter , setter o deleter funciones, haciendo referencia a la propiedad objeto de la clase padre:

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)

También puede agregar un definidor o un eliminador donde antes no había uno en la clase base.

Usando propiedades sin decoradores

Si bien el uso de la sintaxis decorativa (con la @) es conveniente, también es un poco oculto. Puede utilizar propiedades directamente, sin decoradores. El siguiente ejemplo de Python 3.x muestra esto:

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)


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow