如果我有一个包含许多函数的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!
但由于某些原因,我不能只从parse
运行funcs
,因为我收到了一个关键错误:
>>> 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
应该通过parser.py
行导入from funcs import *
,我也不会在foo
globals()
中找到parser.py
当它通过funcs.py
使用时。怎么会发生这种情况?
我最后应该指出,导入parser
然后导入funcs
(但只能按此顺序)允许它按预期工作:
>>> import parser
>>> import funcs
>>> funcs.parse("foo bar")
foo!
bar!
答案 0 :(得分:2)
import module_name
做的事情与from module_name import *
的做法根本不同。
前者创建一个名为module_name
的全局,其类型为module
,其中包含作为属性访问的模块名称。后者为module_name
中的每个名称创建一个全局,但不为module_name
本身创建。
因此,当import funcs
,foo
和bar
未放入globals()
时,execute
找不到它们时就找不到了。< / p>
这样的循环依赖(试图从parser
导入funcs
导入名称而funcs
导入parser
)是不好的。显式优于隐式。不要试图创造这么多魔法。告诉parse()
可用的功能。
答案 1 :(得分:0)
parser
也是内置模块。通常,内置解析器应该加载不是你的。
我会改名,这样你就没有问题。我会仔细考虑您导入模块的顺序以及您需要它们的位置。
答案 2 :(得分:0)
你的“解析器”是一个非常糟糕的主意。
改为做。
def execute(*functions):
for function in functions:
function()
然后你可以打开python并执行以下操作:
>>> import parser
>>> from funcs import foo, bar
>>> parser.execute(foo, bar, bar, foo)
如果没有使用“字符串”,那么生活会变得更简单,其中函数本身就是你真正的意思。