题
以下模块的主要目的,是为某些名称提供一种“恒定”语义。
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']
因此one
和two
都是存在的,但属性访问是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]
不隶属于 StackOverflow