在模块名称空间中填充值

agi*_*liq 1 python module metaprogramming

我有一个python模块.

我想在运行时为它填充一些值,我该怎么做.

例如.我有一个清单,

['A','B','C']

我正在创建具有这些名称的类,并希望它们可用,就像我正常创建它们一样

for el in ['A', 'B', 'C']:
    type(el, (object,), {})
Run Code Online (Sandbox Code Playgroud)

Mik*_*ers 5

我可以想到几种方法来做到这一点......为了(我相信最好)最好的,我们有:

首先,在当前模块上设置属性

# The first way I had of grabbing the module:
mod = __import__(__name__, fromlist=['nonempty'])

# From Roger's suggestion:
import sys
mod = sys.modules[__name__]

for name in ['A', 'B', 'C']:
    class_ = type(name, (object, ), {})
    setattr(mod, name, class_)

print A, B, C
Run Code Online (Sandbox Code Playgroud)

二,设置为当前的全局字典:

for name in ['A', 'B', 'C']:
    class_ = type(name, (object, ), {})
    globals()[name] = class_

print A, B, C
Run Code Online (Sandbox Code Playgroud)

最后,使用exec(eww):

for name in ['A', 'B', 'C']:
    class_ = type(name, (object, ), {})
    exec "%s = class_" % name

print A, B, C
Run Code Online (Sandbox Code Playgroud)

我已经在一个独立的脚本(在哪里__name__ == "__main__")和作为更大包中的模块测试了所有这三个工作.

编辑:关于评论中方法1与方法2的讨论,它们都完全相同.模块的名称空间在模块中存储的dict中定义(这里是文档).从模块级别,您可以通过globals()外部和外部访问它,您可以通过属性或__dict__模块的属性访问它.

一个交互式会话来演示:

Python 2.6.4 (r264:75706, Nov  8 2009, 17:35:59) 
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> mod = sys.modules[__name__]
>>> mod.__dict__ is globals()
True
Run Code Online (Sandbox Code Playgroud)

  • 为什么`__import__`而不是`sys.modules [__ name __]`? (2认同)