Python:动态"from"导入



所以我试图把一堆"from x import x"语句变成这样:

from class_foo import class_foo

变成动态的东西。 我正在尝试传递目录的路径并让它导入其中的所有模块。

def dynamicImport(dirPath):
    filez = os.listdir(dirPath)
    for file in filez:
        if "class" in file:
            oname = file[:-3] #cut off the file extension, trivial
            imp_statement = "from " + oname + " import " + oname
            #when I print imp_statement, I can verify it's being concatenated correctly
            exec(imp_statement)

当我运行此函数并向其传递路径时,语句字符串正在正确创建并且不会产生任何错误,但稍后我将尝试访问其中一个导入的对象,并且会发生这种情况:

foo = class_foo()
NameError: name 'class_foo' is not defined

显然我做错了什么。任何帮助将不胜感激。

exec函数的本地命名空间中的导入语句,因此这是定义名称的位置。当函数结束时,此命名空间将消失,让您一无所有。您可能想要的是类似 exec imp_statement in globals() .

为什么不直接使用__import__()而不是字符串处理?然后,您将获得对模块的引用。然后,您可以使用模块对象上的getattr()找出类引用并将其插入globals()(或者只是将字典传递回调用方,然后调用者可以对其进行globals().update())。

import sys, os
def getClasses(directory):
    classes = {}
    oldcwd = os.getcwd()
    os.chdir(directory)   # change working directory so we know import will work
    for filename in os.listdir(directory):
        if filename.endswith(".py"):
            modname = filename[:-3]
            classes[modname] = getattr(__import__(modname), modname)
    os.setcwd(oldcwd)
    return classes
globals().update(getClasses(r"C:plugin_classes"))

类似的东西。或者,与其用你的模块更新globals(),这可能会破坏你关心的全局变量,不如把类留在字典中并从那里引用它们:

classes = getClasess(r"C:plugin_classes")
for clas in classes.itervalues():
    instance = clas(1, 2, 3)       # instantiate
    instance.dosomething_cool(42)  # call method
Python

>= 2.7 有 importlib(你可以在早期版本的 Python 中使用 importlib

module = importlib.import_module("path.to.module")
MyClass = module.MyClass

假设您的目录结构如下所示:

./   <- you are here
- main.py
- my_package/
    - __init__.py
    - my_module.py

并且您想动态导入my_module.py,以使用它的一些函数,类等。 然后,使用 importlib ,可以在main.py中使用以下代码:

import importlib
pack = "my_package"
mod = "my_module"
module = importlib.import_module("." + mod, pack)
# or, alternatively
module = importlib.import_module(".".join(pack, mod))
module.func("hello") # if my_package/my_module.py defines function "func"
obj = module.MyClass("world") # if my_package/my_module.py defines class "MyClass" 

我已经很久没有使用Python了。 但我认为您的问题可能在于"oname"是一个字符串。 行from class_foo import class_foo不是字符串。 一个艰苦的选择是让你的代码制作一个全新的.py文件,其中包含所有导入。 因此,您可以将所有当前文件以及新导入的内容写入,基本上是以.py结尾的文本文件

看看__import__函数

最新更新