以下模块的主要目的,是为某些名称提供一种“恒定”语义。

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

当使用:

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

因此onetwo都是存在的,但属性访问是diappointing:

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

我在哪里沃尔德希望在这种情况下1。我在哪里错了?

有帮助吗?

解决方案

在描述符协议仅适用于该类的的属性下,不能在一个类的实例的属性。请参阅使用指南为描述符

其他提示

您缺少一个的 STR ()或的unicode ()方法在常量。

添加:

def __unicode__(self):
    return self._name

我认为蟒防止类访问描述符机械,使得它们可以被操纵。否则操纵描述符可以得到非常棘手没有某种“神奇”的功能,如果你已经注意到蟒蛇试图保持了很多访问的语言机械。为了解决这个问题,我常常产生对飞类。例如,您常量类可以声明如下这样:

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

不过说真的,你的目的,你可能是更好的:

class Constants(object):
    def __init__(self, content):
       self._content = content
    def __getattr__(self,key):
       return self._content[key]
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top