所以我试图把一堆"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
>= 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__函数