运行时向模块命名空间注入属性

4 投票
2 回答
1270 浏览
提问于 2025-04-17 14:15

当我写的一个Python模块被导入时,我想根据模块中定义的一个字典的内容,创建一组属性。这里是模块中字典的一小部分:

list_of_constellations = {
   0: Constellation("And", "Andromeda"),
   1: Constellation("Ant", "Antlia"),
   2: Constellation("Aps", "Apus"),
   3: Constellation("Aql", "Aquila"),
}

其中,Constellation是一个命名元组。我想做的是把一组新的属性注入到命名空间中,这些属性的名字是元组中的第一个元素,而它们的值是字典的键。因此,在导入后,可以使用以下属性:

import constellations

print constellations.And   # prints 0
print constellations.Ant   # prints 1

我该怎么做呢?

2 个回答

1

在Python 2.7中:

>>> import constellations
>>> dir(constellations)
['Constellation', 'list_of_constellations', 'namedtuple', 'namespace', ...]
>>> for key, tupl in constellations.list_of_constellations.iteritems():
>>>    setattr(constellations, tupl[0], key)
>>> dir(constellations)
['And', 'Ant', 'Aps', 'Aql', 'Constellation', 'list_of_constellations',
'namedtuple', 'namespace', ...]

如果你使用的是Python 3,把 iteritems() 替换成 items() 就可以了。

你可以用 vars(constellations).update(dict) 来一次性更新属性,而不是一个一个地设置。这里的 dict 是一个字典对象,里面包含了要插入的属性,格式是名字:值。

4

在这个模块里,globals() 函数会返回模块的命名空间,形式是一个字典;你只需要用每个命名元组的第一个元素作为键,就可以设置整数值:

for key, const in list_of_constellations.items():
    globals()[const[0]] = v  # set "And" to 0, etc.

或者在模块外部,可以使用 setattr() 来给模块添加属性:

import constellations

for key, const in constellations.list_of_constellations.items():
    setattr(constellations, constellation[0], v)  # set "And" to 0, etc.

撰写回答