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

当key是迭代器时,使用点表示法在Python中创建字典条目,python,dictionary,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):

我将
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
方法克服这个问题,但我想了解为什么当我使用点表示法时,我的
ObjectiveDict
\setattr\uuuuuuuuu>方法将迭代器作为字符串获取?有没有办法修补我的代码,使之与点符号配合使用?

因为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}

因为这就是
操作符的工作方式,所以属性名将作为字符串传递给
\uuuu setattr\uuuu
。在您的情况下,它将是
'k'
。您需要为k In键使用
:setattr(objd,k,None)
;用点表示法是行不通的。正如@AshwiniChaudhary所说,
foo.bar='baz'
被翻译成
foo.\uuu setattr\uuu('bar','baz')