可以从<module> import *有时不工作吗?</module>

时间:2010-12-02 03:21:39

标签: python import globals

如果我有一个包含许多函数的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!

3 个答案:

答案 0 :(得分:2)

import module_name做的事情与from module_name import *的做法根本不同。

前者创建一个名为module_name的全局,其类型为module,其中包含作为属性访问的模块名称。后者为module_name中的每个名称创建一个全局,但不为module_name本身创建。

因此,当import funcsfoobar未放入globals()时,execute找不到它们时就找不到了。< / p>

这样的循环依赖(试图从parser导入funcs导入名称而funcs导入parser)是不好的。显式优于隐式。不要试图创造这么多魔法。告诉parse()可用的功能。

答案 1 :(得分:0)

  • 导入解析器后打印全局变量以查看它的作用
  • parser也是内置模块。通常,内置解析器应该加载不是你的。 我会改名,这样你就没有问题。
  • 您的导入功能,但解析器从funcs导入*?

我会仔细考虑您导入模块的顺序以及您需要它们的位置。

答案 2 :(得分:0)

你的“解析器”是一个非常糟糕的主意。

改为做。

def execute(*functions):
    for function in functions:
        function()

然后你可以打开python并执行以下操作:

>>> import parser
>>> from funcs import foo, bar 
>>> parser.execute(foo, bar, bar, foo)

如果没有使用“字符串”,那么生活会变得更简单,其中函数本身就是你真正的意思。