Python:动态 "from"导入

标签 python

所以我试图转换一堆“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 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:动态 "from"导入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11108628/

相关文章:

Python递归设置值排列字典

python - 配置 Python Flask App 使用 "create_app"工厂并在模型类中使用数据库

python - 如何使用 yml 文件创建 conda 环境而不出现此错误?

Python 脚本作为服务无法访问 asoundrc 配置文件

python - 寻找二叉树中的最小值,Python

python - Json 正文在 AWS Lambda 函数中使用非英文字符被截断

python - 具有 'internal'/'external' 守护线程的应用程序之间的功能差异

c# - 使用 OpenCV 感知二维图像中长方体的尺寸(或突出点)

python - 从 python 跟踪到 Google Analytics

Python 词干提取(使用 pandas 数据框)