Pergunta

O objetivo principal o módulo seguinte, é fornecer um tipo de semântica "constante" para alguns nomes.

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

Quando usado:

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

Assim one e two estão lá, mas o acesso atributo é diappointing:

>>> num_const.one
<const.Constant object at 0x7faef4871710>
>>> 

Onde eu Wold esperar 1 neste caso. Onde eu estou errado?

Foi útil?

Solução

O protocolo de descritor só funciona em atributos da classe , e não nos atributos de instâncias de uma classe. Veja a How-To Guide for Descritores

Outras dicas

Está faltando um str () ou unicode () em Constantes.

Adicionar:

def __unicode__(self):
    return self._name

Eu penso aulas evita python de acessar as máquinas descritor de modo que eles podem ser manipulados. Caso contrário manipular o descritor poderia ficar muito complicado, sem algum tipo de função 'mágico', e se você tenta python notado para manter um monte de máquinas linguagem acessível. Para contornar esta situação eu sempre gerado a classe na mosca. Por exemplo, você Constantes classe pode ser declarada assim:

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

mas realmente, para você fins que você pode ser melhor com:

class Constants(object):
    def __init__(self, content):
       self._content = content
    def __getattr__(self,key):
       return self._content[key]
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top