我为自己编写了一个简单的函数,它可以筛选我的 Python 文件夹并查找可能的模块所在的位置。我想做的很简单。我传递了一个模块导入字符串,该函数将找到模块的文件夹,在那里 cd,并将其导入到我正在工作的任何环境中,例如:
anyimport('from fun_abc import *')
最初我试过:
class anyimport(object):
def __init__(self, importmodule, pythonpath='/home/user/Python', finddir=finddir):
##################################################################
### A BUNCH OF CODES SCANNING THE DIRECTORY AND LOCATE THE ONE ###
##################################################################
### "pointdir" is where the directory of the file is ###
### "evalstr" is a string that looks like this : ---
### 'from yourmodule import *'
os.chdir(pointdir)
exec evalstr
当我在 iPython Notebook 中对整个内容进行编码时,它可以工作。所以这个问题被我忽略了。然后我发现它不能正常工作,因为函数导入的模块保留在函数的局部变量空间中。
然后我发现了这个 Stack Overflow 讨论 "In Python, why doesn't an import in an exec in a function work?" 。因此,我将代码更改为以下内容:
class anyimport(object):
def __init__(self, importmodule, pythonpath='/home/user/Python', finddir=finddir):
##################################################################
### A BUNCH OF CODES SCANNING THE DIRECTORY AND LOCATE THE ONE ###
##################################################################
### "pointdir" is where the directory of the file is ###
### "evalstr" is a string that looks like this : ---
### 'from yourmodule import *'
sys.path.append(os.path.join(os.path.dirname(__file__), pointdir))
exec (evalstr, globals())
它仍然不起作用。该函数运行时没有错误,但模块对我不可用,例如,如果我运行
script.py
,其中我执行 anyimport('from fun_abc import *')
但没有 fun_abc
中的任何内容。 Python 会告诉我“NameError: name 'fun_you_want' is not defined”。有没有人愿意为我指出如何解决这个问题的正确方向?
感谢您的关注,非常感谢您的帮助!
注意力:
除了@Noya 的现场回答,必须通过范围才能使
exec
工作,以避免“ImportError”,您需要在运行 exec
之前添加这一行:sys.path.append(os.path.join(os.path.dirname(__file__), pointdir))
exec (evalstr, scope)
这是因为我们对
sys.path
的修改假定当前工作目录始终在 main/
中。我们需要将父目录添加到 sys.path
。有关解决此问题的更多信息,请参阅此 Stack Overflow 讨论 "ImportError: No module named - Python"。 最佳答案
exec
在当前范围内执行代码。在函数内部,这意味着 (function-) 局部作用域。
您可以通过给 exec
一个元组来告诉 (code, scope)
将变量放在另一个范围内。例如,您可以使用 globals()
使名称在模块级别可用。
请注意,globals
因此,在您的示例中,您必须将所需的范围传递给您的实用程序函数:
anyimport.py:
class anyimport(object):
def __init__(self, importmodule, scope):
exec (importmodule, scope)
测试.py:
a = 42
b = 'foo'
主要.py:
from anyimport import anyimport
if __name__ == '__main__':
anyimport('from test import *', globals())
# 42 foo
print a, b
用
python main.py
测试它。确保所有文件都存在于当前目录中。替代方案
如果您不一定要使用
exec
,更优雅的方法是使用 Python 提供的导入实用程序。以下取自 https://stackoverflow.com/a/4526709/453074 ,等效于
from some.package import *
:globals().update(importlib.import_module('some.package').__dict__)
.
关于python - 如何使来自 exec ("import xxx") 的模块在 Python 函数中可用?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28481170/