动态加载类并获取引用

时间:2017-12-21 06:35:33

标签: python

Python正在努力。我并不认为加载一些模块并动态地实例化类是如此困难。我在这里已经阅读了其他几个问题,但是所提供的解决方案似乎都不适用于我。

我的文件夹结构

./coin.py
./exchanges/
    /bittrex.py (contains Bittrex class)
    /kraken.py (contains Kraken class)
    ...

我的目标

以少量代码,没有任何黑客手段,动态导入每个模块,并获取对类中的类的引用,以便我可以实例化它们并获取它们的属性。

我当前的代码

import glob, exchanges, dirfiles, isfile, inspect

dirfiles = glob.glob(dirname(__file__) + "/exchanges/*.py")
__all__ = [ basename(f)[:-3] for f in dirfiles if isfile(f) and not f.endswith('__init__.py')]

class Indicator(object):
    def __init__(self): 
        for exchange in __all__:
            class_name = exchange.capitalize()
            class_ = getattr(exchange, class_name)

            self.EXCHANGES.append({
                'code': exchange,
                'name': class_name,
                'instance': class_(self)
            })

然而,上面的代码和我尝试过的许多不同的排列总是以它将我想要的类引用解释为字符串。

2 个答案:

答案 0 :(得分:1)

Importlib允许动态加载模块和包,os.listdir简化了查找文件的过程:

import os
import importlib   

for p in os.listdir('exchanges'):
    if p[-3:] == '.py' and p != '__init__.py':
         module_ = importlib.import_module("exchanges.%s" % p[:-3])
         class_ = getattr(module_, class_name)

         self.EXCHANGES.append({
             'code': exchange,
             'name': class_name,
             'instance': class_(self)
         })

我不确定代码中的capitalze。如果它是每个文件中的函数,则可以使用:

执行它
capitalize = getattr(module_, 'capitalize')
class_name = capitalize()

答案 1 :(得分:0)

您可以使用 importlib 模块。

请查看以下示例:

目录结构

Current_Dir
    |
    |---qwerty.py
    |
    |---dinesh 
          |
          |--dsp.py -->> This file has class 'call_me' 

dsp.py代码:

class call_me(object):

    def __init__(self):
        pass

    def run(self):
        print("Dinesh")

qwerty.py代码:

import sys
import os
import importlib

lib_path = os.getcwd() + os.sep + 'dinesh'
sys.path.insert(0,lib_path)

mod = importlib.import_module('dsp')
a = getattr(mod,'call_me')
s = a()
s.run()

<强>输出

C:\Users\punddin\PycharmProjects\demo>python qwerty.py
Dinesh