gpt4 book ai didi

python - 如何使来自 exec ("import xxx"的模块在 Python 函数中可用?

转载 作者:太空宇宙 更新时间:2023-11-03 13:16:28 26 4
gpt4 key购买 nike

我自己编写了一个简单的函数来筛选我的 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 在当前范围内执行代码。在函数内部,这意味着(函数-)局部作用域。

你可以告诉 exec 通过给它一个元组 (code, scope) 把变量放在另一个范围内。例如,您可以使用 globals() 使名称在模块级别可用。

请注意,globals

is always the dictionary of the current module (inside a function or method, this is the module where it is defined, not the module from which it is called).

因此,在您的示例中,您必须将所需范围传递给实用程序函数:

anyimport.py:

class anyimport(object):
def __init__(self, importmodule, scope):
exec (importmodule, scope)

测试.py:

a = 42
b = 'foo'

main.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 *:

[...] it's more convenient to user importlib:

globals().update(importlib.import_module('some.package').__dict__) 

.

关于python - 如何使来自 exec ("import xxx"的模块在 Python 函数中可用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28481170/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com