当键是迭代器时使用点表示法在 Python 中创建字典条目
Creating dictionary entries in Python using dot notation when key is an iterator
我像这样对 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
将迭代器作为字符串获取?有没有办法修补我的代码,使其与点符号一起工作?
因为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}
!
我像这样对 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
将迭代器作为字符串获取?有没有办法修补我的代码,使其与点符号一起工作?
因为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}
!