在模块名称空间中填充值

时间:2009-11-22 14:30:08

标签: python metaprogramming module

我有一个python模块。

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

EG。我有一个清单,

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

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

for el in ['A', 'B', 'C']:
    type(el, (object,), {})

2 个答案:

答案 0 :(得分: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

其次,设置为当前全局变量dict:

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

print A, B, C

最后,使用exec(eww):

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

print A, B, C

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

编辑:关于评论中方法1与方法2的讨论,它们都完全相同。模块的名称空间在存储在模块(here are the docs)上的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

答案 1 :(得分:2)

动态创建类并使其在模块mymodule中可用:

import mymodule
for el in ['A', 'B', 'C']:
    setattr(mymodule, el, type(el, (object,), {}))

要在当前模块中创建类,请使用Mike's answer中的方法。