10

所以我试图把一堆“从 x 导入 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

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

4

5 回答 5

12

您正在exec函数的本地命名空间中使用 import 语句,因此这是定义名称的地方。当函数结束时,这个命名空间就消失了,你什么都没有了。您可能想要的是类似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
于 2012-06-19T20:17:01.123 回答
9

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

module = importlib.import_module("path.to.module")
MyClass = module.MyClass
于 2015-03-11T23:15:34.370 回答
0

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

./   <- 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" 
于 2019-09-26T14:39:44.767 回答
-2

自从我使用 Python 以来已经有很长时间了。但我认为你的问题可能在于“oname”是一个字符串。该行 from class_foo import class_foo不是字符串。一个艰苦的选择是让您的代码创建一个全新的 .py 文件,该文件将包含所有导入。因此,您可以将所有当前文件以及新的导入基本上写入以 .py 结尾的文本文件

于 2012-06-19T20:15:56.037 回答
-3

看一下__import__函数

于 2012-06-19T20:15:35.823 回答