【发布时间】:2011-05-18 21:31:23
【问题描述】:
如果我有一个包含大量函数的 python 模块,可以这样说:
#funcs.py
def foo() :
print "foo!"
def bar() :
print "bar!"
我还有另一个模块,旨在从字符串中解析函数列表并运行这些函数:
#parser.py
from funcs import *
def execute(command):
command = command.split()
for c in command:
function = globals()[c]
function()
然后我可以打开python并执行以下操作:
>>> import parser
>>> parser.execute("foo bar bar foo")
foo!
bar!
bar!
foo!
我想向funcs.py 添加一个便利函数,它允许将函数列表作为函数本身调用:
#funcs.py (new version)
import parser
def foo() :
print "foo!"
def bar() :
print "bar!"
def parse(commands="foo foo") :
parser.execute(commands)
现在我可以从解析器本身递归解析:
>>> import parser
>>> parser.execute("parse")
foo!
foo!
>>> parser.execute("parse bar parse")
foo!
foo!
bar!
foo!
foo!
但由于某种原因,我不能只从funcs 运行parse,因为我得到一个关键错误:
>>> import funcs
>>> funcs.parse("foo bar")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "funcs.py", line 11, in parse
parser.execute(commands)
File "parser.py", line 6, in execute
function = globals()[c]
KeyError: 'foo'
所以即使foo 应该通过from funcs import * 行导入parser.py,当通过funcs.py 使用它时,我在parser.py 的globals() 中找不到foo。怎么会这样?
最后我应该指出,导入 parser 然后 funcs(但只能按此顺序)可以使其按预期工作:
>>> import parser
>>> import funcs
>>> funcs.parse("foo bar")
foo!
bar!
【问题讨论】:
-
你应该考虑使用装饰器来枚举你关心的函数。这将大大简化您的代码。
-
@Ignacio 他会怎么做呢?我没看到
-
@Rafe:在某处的注册表中记录名称和函数,然后从注册表中获取函数,而不是通过
globals()抓取。 -
getattr(funclib, 'myfunc')() 无需导入 *。
-
@Ignacio 我明白了。好主意,这似乎是一个相当干净的实现