0

我有一个类似字典的对象,其中存储描述符:

 class MyDict(object):
    def __init__(self):
        dict.__init__(self)

    def __getitem__(self, key):
        v = dict.__getitem__(self, key)
        if hasattr(v, '__get__'):
           return v.__get__(None, self)
        return v

class MyDescriptor(object):
    def __init__(self, value, attrib={}):
        self.__value = value
        self.attrib= attrib

    def __get__(self, instance, owner):
        return self.__value

    def __set__(self, instance, value):
        self.__value = value

我希望能够做到以下几点:

d = MyDict()
d['1'] = MyDescriptor("123", {"name": "val"})
print d['1']                     # prints "123"
print d['1'].attrib["name"]      # prints "val"

我的课不工作。请你帮助我好吗?

4

2 回答 2

1

我不确定这是否能解决您的用例,但就实现您所说的结果而言,您可以简单地删除您的MyDict课程并使用普通的dict

d = {}

然后,向返回的类添加一个__str__方法,您将获得您所描述的结果。MyDescriptorself.__value

>>> d['1'] = MyDescriptor("123", {"name": "val"})
>>> d['1']                     
123
>>> d['1'].attrib["name"] 
val
于 2012-12-05T15:02:39.107 回答
1

除非显示了更多内容,否则您的解决方案看起来对于解决您的问题来说是不必要的复杂。为什么不简单地这样做:

class MyObject(object):
    def __init__(value, attrib=None):
        self.__value = value
        self.attrib = {} if attrib is None else attrib

    def __str__(self):
        return __value

d = {}
d['1'] = MyObject("123", {"name": "val"})
print d['1']                     # prints "123"
print d['1'].attrib["name"]      # prints "val"

至于为什么你的代码不起作用,有几个明显的问题。

  • 从您对 的各种特殊方法的调用来看__dict__,这似乎MyDict是为了子类dict化,所以定义应该是:

    class MyDict(dict):
        ...
    
  • 虽然不是不正确,但更好的做法是使用super而不是直接引用基类,所以dict.__init__(self)会成为super(MyDict, self).__init__()dict.__getitem__(self, key)成为super(MyDict, dict).__getitem__(key)

  • 您要求sill工作的电话,但与方法规范不符。您应该将其称为v.__get__(self, MyDict). 但是,您使用它的方式实际上是__get__多余的,我认为这种用法是主要问题所在。

  • 在课堂MyDescriptor上,提前绑定会给你带来意想不到的效果attrib。有关声明它的更好方法,请参见上面的示例。

我怀疑你真正想要的不是描述,而是一个看起来像字符串的对象(对于“看起来像”的某些定义),但有一个属性attrib。为此,无需尝试创建完全用于不同用例的描述符。我上面的示例给出了一个满足“看起来像”字符串的对象要求的类,其中“看起来像”意味着它打印一个字符串,但这是另一个可能更像你想要的:

class MyString(str):
    def __init__(self, value, attrib=None):
        super(MyString, self).__init__(value)
        self.attrib = {} if attrib is None else attrib
于 2012-12-05T15:29:21.870 回答