Python:动态“从”导入

时间:2012-06-19 20:11:17

标签: python

所以我试图将一堆“来自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

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

5 个答案:

答案 0 :(得分:9)

你在函数的本地命名空间中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

答案 1 :(得分:8)

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

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

答案 2 :(得分: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" 

答案 3 :(得分:-2)

查看__import__功能

答案 4 :(得分:-2)

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

结尾的文本文件