将__get __,__ set__与字典项一起使用?

时间:2016-07-25 16:49:47

标签: python dictionary

有没有办法制作一个使用set和get语句的函数字典,然后将它们用作set和get函数?

class thing(object):
    def __init__(self, thingy)
        self.thingy = thingy
    def __get__(self,instance,owner):
        return thingy
    def __set__(self,instance,value):
        thingy += value

theDict = {"bob":thing(5), "suzy":thing(2)}

theDict["bob"] = 10

想要的结果是10进入set函数并添加到现有的5

print theDict["bob"]
>>> 15

实际结果是字典用数值

替换该条目
print theDict["bob"]
>>> 10

为什么我不能像...那样的功能?     theDict ["摆锤"]添加(10)。 是因为它建立了一个现有的,已经非常好用的功能,它使用了set和get。与我合作的案例是一个边缘案例,重新编程所有内容以便为这一案件工作是没有意义的。

我需要一些方法来存储这个set / get thingy的实例,这些实例是可访问的,但是不会创建一些可能破坏现有引用的深度层。

请不要询问实际代码。它需要使用代码页来封装问题。

3 个答案:

答案 0 :(得分:1)

不,因为要执行theDict["bob"] = 10,Python运行时不会调用theDict["bob"]的所有先前值的任何方法。它不像myObject.mydescriptor = 10调用描述符设置器那样。

好吧,如果引用数量达到零,也许会在前一个值上调用__del__,但是不要去那里!

如果你想做这样的事情,那么你需要改变字典的工作方式,而不是内容。例如,你可以继承dict(通常警告你,你是邪恶的,坏的和错的,写一个非Liskov替代的派生类)。或者您可以从头开始实现collections.MutableMapping的实例。但我不认为有任何方法可以使用存储在其中的特殊值来劫持dict的正常操作。

答案 1 :(得分:1)

如果你能(也)使用知道你的Thing类的字典的专门版本并单独处理它,你可以这样做:

class Thing(object):
    def __init__(self, thingy):
        self._thingy = thingy
    def _get_thingy(self):
        return self._thingy
    def _set_thingy(self, value):
        self._thingy += value

    thingy = property(_get_thingy, _set_thingy, None, "I'm a 'thingy' property.")

class ThingDict(dict):
    def __getitem__(self, key):
        if key in self and isinstance(dict.__getitem__(self, key), Thing):
            return dict.__getitem__(self, key).thingy
        else:
            return dict.__getitem__(self, key)

    def __setitem__(self, key, value):
        if key in self and isinstance(dict.__getitem__(self, key), Thing):
            dict.__getitem__(self, key).thingy = value
        else:
            dict.__setitem__(self, key, value)


theDict = ThingDict({"bob": Thing(5), "suzy": Thing(2), "don": 42})

print(theDict["bob"])  # --> 5
theDict["bob"] = 10
print(theDict["bob"])  # --> 15

# non-Thing value
print(theDict["don"])  # --> 42
theDict["don"] = 10
print(theDict["don"])  # --> 10

答案 2 :(得分:0)

theDict["bob"] = 10只是将10分配给bob的密钥theDict。 我认为你首先应该了解魔术方法__get____set__。转到:https://docs.python.org/2.7/howto/descriptor.html使用类可能比dict更容易。