How to call a dynamically loaded module without raising NameError: name 'name' is not defined

How to call a dynamically loaded module without raising NameError: name 'name' is not defined

我正在尝试创建一个 'plugin' 系统,将 python 文件(或包)放在 'plugins' 文件夹中,然后重新加载脚本将动态调用函数在这些文件中。

我有以下文件结构

main.py
plugins -
         |- test.py
         |- status.py

我像这样导入 test.py/status.py 模块:

sys.path.append('plugins')

plugins_list = os.listdir('plugins')
plugins_list.remove('__pycache__') # prevenet error from being raised

for module in plugins_list:
    importlib.import_module('plugins.'+module[:-3])
    print("Imported {}".format('plugins.'+module[:-3]))

脚本运行没问题。我试试 print(sys.modules.keys())plugins.testplugins.status 确实被导入了。但是现在当我尝试调用内部的任何函数时,会引发名称错误 NameError: name 'plugins' is not defined

这将我带到 Python custom module name not defined,他们解释说 plugins.status.get_status() 不起作用。我不知何故必须以不同的方式导入它。问题是我使用了 importlib,所以我不确定如何实现它。

我看过 documentation page:

importlib.import_module(name, package=None)

Import a module. The name argument specifies what module to import in absolute or relative terms (e.g. either pkg.mod or ..mod). If the name is specified in relative terms, then the package argument must be set to the name of the package which is to act as the anchor for resolving the package name (e.g. import_module('..mod', 'pkg.subpkg') will import pkg.mod).

The import_module() function acts as a simplifying wrapper around importlib.__import__(). This means all semantics of the function are derived from importlib.__import__(). The most important difference between these two functions is that import_module() returns the specified package or module (e.g. pkg.mod), while __import__() returns the top-level package or module (e.g. pkg).

似乎 __import__() 可以解决我的问题,但它建议我不要使用它。

此外,我想定义一些东西,因为第二个 importlib 争论可能会解决问题,但我不确定是什么

如何才能使函数成为运行?

当您 运行 importlib.import_module('plugins.'+module[:-3]) 时,返回的值是导入的模块。它没有被分配给任何东西,所以它几乎在导入后就被清理干净了。可以动态添加到命名空间,但不推荐。

尝试这样的操作,将导入的模块分配给字典,然后您可以根据模块名称通过字典引用该模块:

plugin_dict = {}

for module in plugins_list:
    modname = module[:-3]
    plugin_dict[modname] = importlib.import_module('plugins.'+modname)
    print("Imported {}".format('plugins.'+module[:-3]))
    
    
    
plugin_dict['status'].get_status()