Acceso atributo anulado no funciona (como se esperaba)
-
18-09-2019 - |
Pregunta
El objetivo principal del módulo siguiente, es proporcionar un tipo de semántica "constantes" de algunos nombres.
class ConstantError(Exception):
def __init__(self, msg):
self._msg = msg
class Constant(object):
def __init__(self, name):
self._name = name
def __get__(self, instance, owner):
return instance._content[self._name]
def __set__(self, instance, value):
raise ConstantError, 'Illegal use of constant'
class Constants(object):
def __init__(self, content):
self._content = content
for k in self._content:
setattr(self, k, Constant(k))
num_const = Constants({
'one': 1,
'two': 2
})
Cuando se utiliza:
>>> from const import *
>>> dir(num_const)
['__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__', '_content', 'one', 'two']
Así one
y two
están ahí, pero el acceso es diappointing atributo:
>>> num_const.one
<const.Constant object at 0x7faef4871710>
>>>
Donde Wold esperar 1
en este caso. Dónde estoy mal?
Solución
El protocolo descriptor sólo funciona en atributos de la clase , no en los atributos de instancias de una clase. Vea la Guía práctica para los descriptores
Otros consejos
se echa en falta una str () o Unicode () en Constantes.
Añadir:
def __unicode__(self):
return self._name
Creo pitón impide el acceso a las clases de la maquinaria descriptor de modo que puedan ser manipulados. De lo contrario, la manipulación del descriptor podría ser muy difícil sin algún tipo de función 'mágica', y si usted ha notado intentos pitón para mantener una gran cantidad de la maquinaria lenguaje accesible. Para evitar esto a menudo he generado la clase sobre la marcha. Por ejemplo, la clase le Constantes podría ser declarado así:
class Constants(object):
def __new__(cls, content):
class _Constants(object):
pass
constants = _Constants
constants._content = content
for k in constants._content:
setattr(_Constants, k, Constant(k))
return constants
pero en realidad, para usted propósitos que podría ser mejor con:
class Constants(object):
def __init__(self, content):
self._content = content
def __getattr__(self,key):
return self._content[key]