2012-04-29 12 views
9
class Books(): 
    def __init__(self): 
     self.__dict__['referTable'] = 1 

    @property 
    def referTable(self): 
     return 2 

book = Books() 
print(book.referTable) 
print(book.__dict__['referTable']) 

de reproducción:¿Versión incorporada sin datos de la propiedad?

[email protected]:~/Desktop$ python3 test.py 
2 
1 

Books.referTablebeing a data descriptor no se ve ensombrecido por book.__dict__['referTable']:

La función property() se implementa como un descriptor de datos. En consecuencia, las instancias no pueden anular el comportamiento de una propiedad.

Para sombrearlo, en lugar de property descriptor incorporado debo usar mi propio descriptor. ¿Hay un descriptor incorporado como property pero que no es de datos?

+1

¿Qué estás tratando de hacer aquí? ¿Qué intenta lograr que no se pueda lograr cambiando la función en la que está utilizando '' @ property'' en las funciones? –

+0

@Lattyware, estoy tratando de hacer un descriptor perezoso. A veces quiero que 'referTable' se establezca en' __init__'. En otros casos, quiero que el descriptor calcule el valor y anule el descriptor de la misma manera que en '__init__'. Aquí (http://blog.pythonisito.com/2008/08/lazy-descriptors.html) se ha convertido en un descriptor separado para eso, que me funcionaría. En mi caso, quiero simplificarlo, utilizando si es posible un descriptor incorporado, y 'property' no funciona para mí. – warvariuc

+0

'Simplificarlo'? ¿Podría aclarar lo que quiere simplificar? ¿Por qué el ejemplo que vincula no funciona para usted? –

Respuesta

5

Para ampliar mi comentario, ¿por qué no simplemente algo como esto:

>>> class Books(): 
...  def __init__(self): 
...   self.__dict__['referTable'] = 1 
...  @property 
...  def referTable(self): 
...   try: 
...    return self.__dict__['referTable'] 
...   except KeyError: 
...    return 2 
... 
>>> a = Books() 
>>> a.referTable 
1 
>>> del a.__dict__['referTable'] 
>>> a.referTable 
2 

Ahora, me gustaría señalar que no creo que esto es un buen diseño, y que sería mucho mejor apagado utilizando una variable privada en lugar de acceder __dict__ directamente. Por ejemplo:

class Books(): 
    def __init__(self): 
     self._referTable = 1 

    @property 
    def referTable(self): 
     return self._referTable if self._referTable else 2 

En resumen, la respuesta es no, no hay alternativa a property() que funciona en la forma que desee en la biblioteca estándar de Python.

2

Hay algo muy similar a un dispositivo integrado en el descriptor de datos no - el atributo de clase:

class Books(): 

    referTable = 'default' 

    def __init__(self, referTable=None): 
     if referTable is not None: 
      self.referTable = referTable 


book = Books() 
print(book.referTable) 
# default 
book.referTable = 'something specific' 
print(book.referTable) 
# something specific 

Si necesita algo más parecido a una propiedad (por ejemplo, se desea una función para hacer algunas pesada de levantamiento de la primera vez, pero luego utilizar ese primer valor para todas las referencias futuras), entonces usted tendrá que construir por sí mismo:

class OneTime(object): 

    def __init__(self, method): 
     self.name = method.__name__ 
     self.method = method 

    def __get__(self, inst, cls): 
     if inst is None: 
      return self 
     result = self.method(inst) 
     inst.__dict__[self.name] = result 
     return result 

class Books(object): 

    @OneTime 
    def referTable(self): 
     print 'calculating' 
     return 1 * 2 * 3 * 4 * 5 

b = Books() 
print b.__dict__ 
print b.referTable 
print b.__dict__ 
print b.referTable 

con los siguientes resultados:

{} 
calculating 
120 
{'referTable': 120} 
120 
Cuestiones relacionadas