当前位置:  开发笔记 > 编程语言 > 正文

如何动态加载Python类

如何解决《如何动态加载Python类》经验,为你挑选了5个好方法。



1> Jason Baker..:

从python文档中,这是你想要的功能:

def my_import(name):
    components = name.split('.')
    mod = __import__(components[0])
    for comp in components[1:]:
        mod = getattr(mod, comp)
    return mod

简单__import__不起作用的原因是因为任何超出包字符串中第一个点的内容都是您要导入的模块的属性.因此,这样的事情是行不通的:

__import__('foo.bar.baz.qux')

你必须像这样调用上面的函数:

my_import('foo.bar.baz.qux')

或者就你的例子而言:

klass = my_import('my_package.my_module.my_class')
some_object = klass()

编辑:我有点偏僻.你基本上想要做的是:

from my_package.my_module import my_class

仅当您有一个空的 fromlist时,才需要上述功能.因此,适当的调用将是这样的:

mod = __import__('my_package.my_module', fromlist=['my_class'])
klass = getattr(mod, 'my_class')



2> chadrik..:

如果你不想自己动手,那么pydoc模块中有一个功能就是这样:

from pydoc import locate
my_class = locate('my_package.my_module.MyClass')

这种方法优于此处列出的其他方法的优点是可以在提供的虚线路径上locate找到任何 python对象,而不仅仅是模块中直接的对象.例如my_package.my_module.MyClass.attr.

如果你很好奇他们的食谱是什么,这里的功能是:

def locate(path, forceload=0):
    """Locate an object by name or dotted path, importing as necessary."""
    parts = [part for part in split(path, '.') if part]
    module, n = None, 0
    while n < len(parts):
        nextmodule = safeimport(join(parts[:n+1], '.'), forceload)
        if nextmodule: module, n = nextmodule, n + 1
        else: break
    if module:
        object = module
    else:
        object = __builtin__
    for part in parts[n:]:
        try:
            object = getattr(object, part)
        except AttributeError:
            return None
    return object

它依赖于pydoc.safeimport功能.以下是有关的文档:

"""Import a module; handle errors; return None if the module isn't found.

If the module *is* found but an exception occurs, it's wrapped in an
ErrorDuringImport exception and reraised.  Unlike __import__, if a
package path is specified, the module at the end of the path is returned,
not the package at the beginning.  If the optional 'forceload' argument
is 1, we reload the module from disk (unless it's a dynamic extension)."""



3> Adam Spence..:
import importlib

module = importlib.import_module('my_package.my_module')
my_class = getattr(module, 'MyClass')
my_instance = my_class()


一旦您动态导入模块,您就可以通过模块访问该类

4> Stan..:
def import_class(cl):
    d = cl.rfind(".")
    classname = cl[d+1:len(cl)]
    m = __import__(cl[0:d], globals(), locals(), [classname])
    return getattr(m, classname)


这是干净的解决方案!您可以考虑使用:`(modulename,classname)= cl.rsplit('.',2)`
@vdboor`rsplit('.',1)`?

5> Javier Buzzi..:

如果您使用的是Django,则可以使用它。是的,我知道OP并没有要求使用django,但是我遇到了这个问题,寻找Django解决方案,没有找到一个解决方案,并将其放在这里供下一个寻找它的下一个男孩/女孩使用。

# It's available for v1.7+
# https://github.com/django/django/blob/stable/1.7.x/django/utils/module_loading.py
from django.utils.module_loading import import_string

Klass = import_string('path.to.module.Klass')
func = import_string('path.to.module.func')
var = import_string('path.to.module.var')

请记住,如果您要导入没有.re或的东西,请argparse使用:

re = __import__('re')

推荐阅读
落单鸟人
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有