l'accès d'attribut ne fonctionne pas de substitution (comme prévu)
-
18-09-2019 - |
Question
L'objectif principal du module suivant, est de fournir une sorte de sémantique « constante » pour certains noms.
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
})
Quand il est utilisé:
>>> 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']
one
et two
sont là, mais l'accès d'attribut est diappointing:
>>> num_const.one
<const.Constant object at 0x7faef4871710>
>>>
Où je Wold attendre 1
dans ce cas. Où suis-je tort?
Autres conseils
Il vous manque un str méthode () ou unicode () Constantes.
Ajouter:
def __unicode__(self):
return self._name
Je pense que python empêche les classes d'accéder à la machinerie de descripteur afin qu'ils puissent être manipulés. Sinon, la manipulation du descripteur pourrait être très difficile sans une sorte de fonction « magique », et si vous avez remarqué essaie de python de garder beaucoup de machines de langage accessible. Pour contourner cela, je l'ai souvent généré la classe à la volée. Par exemple, la classe vous Constantes pourrait être déclarée comme ceci:
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
mais vraiment, pour vous besoins que vous pourriez être mieux avec:
class Constants(object):
def __init__(self, content):
self._content = content
def __getattr__(self,key):
return self._content[key]