描述符为dict值

时间:2012-12-05 14:41:25

标签: python dictionary descriptor

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

 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"

我的班级不起作用。你能帮我吗?

2 个答案:

答案 0 :(得分:1)

我不确定这是否能解决您的使用案例,但就实现您所声明的结果而言,您只需删除MyDict课程并使用普通的dict

d = {}

然后,在返回__str__的{​​{1}}课程中添加MyDescriptor方法,您将获得您所描述的结果。

self.__value

答案 1 :(得分: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)

  • 您对获取窗台的调用工作正常,但与方法规范不符。你应该 将其称为v.__get__(self, MyDict)。但是,你使用它的方式实际上会使__get__变得多余,我认为这是主要问题所在的用法。

  • 在课程MyDescriptor中,early binding会为attrib提供意外结果。请参阅上面的示例,以获得更好的声明方式。

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

class MyString(str):
    def __init__(self, value, attrib=None):
        super(MyString, self).__init__(value)
        self.attrib = {} if attrib is None else attrib