所以我试图转换一堆“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/