重写的属性访问不起作用(如预期的那样)

2024-04-19 11:29:31 发布

您现在位置:Python中文网/ 问答频道 /正文

下面模块的主要目标是为一些名称提供一种“常量”语义。你知道吗

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是存在的,但是属性access是:

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

在这种情况下,我期望1。我错在哪里?你知道吗


Tags: instancenameselfobjectinitdefmsgcontent
3条回答

常量中缺少str()或unicode()方法。你知道吗

添加:

def __unicode__(self):
    return self._name

我认为python阻止类访问描述符机制,以便对它们进行操作。否则,如果没有某种“神奇”的函数,操纵描述符可能会变得非常棘手,如果您注意到python试图保持许多语言机器的可访问性的话。为了解决这个问题,我经常动态生成类。例如,可以这样声明常量类:

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]

描述符协议只适用于类的属性,而不适用于类实例的属性。参见How-To Guide for Descriptors

相关问题 更多 >