当key是迭代器时,使用点表示法在Python中创建字典条目

时间:2015-02-10 10:48:02

标签: python dictionary

我已将dict分类为:

class ObjectiveDict(dict):

    def __getattr__(self, name):
        if name in self:
            return self[name]
        else:
            raise AttributeError("No such attribute: " + name)

    def __setattr__(self, name, value):
        """
        IMPORTANT NOTICE: when "name" is an iterator of an iterable, will not work, must use [] syntax
        """
        self[name] = value

    def __delattr__(self, name):
        if name in self:
            del self[name]
        else:
            raise AttributeError("No such attribute: " + name)

现在我有类似的东西:

objd = ObjectiveDict({'a':1, 'b':2, 'c':3})
objd.d = 4

这很有效,输出:

{'a': 1, 'b': 2, 'c': 3, 'd': 4}

但是,如果我有一个我要附加到objd的键列表,让我们假设使用默认值,它使用我用于迭代器的名称来创建一个键来迭代列表,即:

keys = ['key1', 'key2', 'key3']
for k in keys:
    objd.k = None

输出:

{'a': 1, 'b': 2, 'c': 3, 'd': 4, 'k': None}

我知道我可以使用objd[k] = None或使用setattr方法解决这个问题,但我想理解为什么当我使用点符号时我的__setattr__方法ObjectiveDict 1}}将迭代器作为字符串?有没有办法修补我的代码,所以它使用点符号?

1 个答案:

答案 0 :(得分:5)

因为Python是连贯的。

在第一种情况下,您对objd.d = 4感到满意,已翻译为objd['d'] = 4。但它可能是:

d = 'e'
objd.d = 4

你仍然会有{'a': 1, 'b': 2, 'c': 3, 'd': 4}(希望 {'a': 1, 'b': 2, 'c': 3, 'e': 4})。

所以当你写下第二种情况时:

keys = ['key1', 'key2', 'key3']
for k in keys:
    objd.k = None

您只需重复objd.k = None,即三次翻译为objd['k'] = None

点符号无法使用名称的,您只能使用名称本身。

您可以使用以下方式使其正常工作:

def __setattr__(self, name, value):
    self[eval(name)] = value

但我真的很劝你不要那样做!在第一种情况下,你会得到:

d = 'e'
objd.d = 4
objd

=>输出:{'a': 1, 'b': 2, 'c': 3, 'e': 4}