【问题标题】:How do I dynamically reload a module in a custom package?如何在自定义包中动态重新加载模块?
【发布时间】:2014-09-03 07:41:19
【问题描述】:

我正在尝试重新加载我编写的整个自定义模块包。

我在这里查看了another question,但它看起来不适用于我的情况。

modules/__init__.py

# based on info from https://stackoverflow.com/questions/1057431/loading-all-modules-in-a-folder-in-python
import os
for module in os.listdir(os.path.dirname(__file__)):
    if module[0:8] != '__init__' and module[-3:] == '.py':
        if module in dir(os.path.dirname(__file__)):
            reload(module)
        else:
            __import__(module[:-3], locals(), globals())
del module
del os

加载模块:

import modules
def loadModule(self, moduleName):
    """
    Load the module with the give name
    i.e. "admin" would load modules/admin.py

    Args:
        moduleName (str): name of the module (admin would load the admin.py file)

    Returns:
        boolean: success or failure of load

    Raises:
        None
    """
    retLoadedCorrectly = False
    # reload everything to dynamically pick up new stuff
    reload(modules)

    # grab the module
    try:
        m = getattr(modules, moduleName)

        # save it
        self.loadedModules[m.commandName] = {'module': moduleName, 'admin': m.adminOnly, 'version': m.version}

        # Yay it loaded :)
        retLoadedCorrectly = True

        # log it
        self.log('Loaded module: {0}, {1}, {2}, {3}'.format(moduleName, m.commandName, m.adminOnly, m.version))
    except AttributeError:
        self.log('Failed to load module: {0}'.format(moduleName), level='WARNING')

    return retLoadedCorrectly

如果我调用loadMudule("example"),它将按预期加载和运行。然后如果我更改示例,然后再次调用 loadModules 方法,则它不会接受更改。

我读到了importlib,但看起来它只是 python 3,我使用的是 python 2.7.6

如果这是一种不好的做法,请务必为我指明一个更好的方向!

【问题讨论】:

  • importlib 在 python 2 中
  • 它似乎只有import_module,我认为这只是__import__的一个包裹

标签: python python-2.7 python-module


【解决方案1】:

感谢 Freenode 上的 dwfreed 为我指明了正确的方向。 https://github.com/myano/jenni/blob/master/modules/reload.py#L40

[02:27] <dwfreed> shortdudey123: basically, use the imp module to directly access python's base importer, re-import the module from the source, and then replace it in sys.modules

对于那些想知道我的最终代码的人......

modules/__init__.py:

# based on info from http://stackoverflow.com/questions/1057431/loading-all-modules-in-a-folder-in-python
# more info in my own question: http://stackoverflow.com/questions/24718759/how-do-i-dynamically-reload-a-module-in-a-custom-package
import os
import sys
import imp

# based off of https://github.com/myano/jenni/blob/master/modules/reload.py#L40
def reload(moduleName):
    name = '{0}.{1}'.format(os.path.dirname(__file__).split('/')[-1:][0], moduleName)
    if name in sys.modules.keys():
        filePath = sys.modules[name].__file__
        if filePath.endswith('.pyc') or filePath.endswith('.pyo'):
            filePath = filePath[:-1]
        module = imp.load_source(name, filePath)
        sys.modules[name] = module
    else:
        pass

for module in os.listdir(os.path.dirname(__file__)):
    if module[0:8] != '__init__' and module[-3:] == '.py':
        name = '{0}.{1}'.format(os.path.dirname(__file__).split('/')[-1:][0], module[:-3])
        __import__(module[:-3], locals(), globals())

然后加载并重新加载:

def loadModule(self, moduleName):
    """
    Load the module with the give name
    i.e. "admin" would load modules/admin.py

    Args:
        moduleName (str): name of the module (admin would load the admin.py file)

    Returns:
        boolean: success or failure of load

    Raises:
        None
    """
    retLoadedCorrectly = False
    # reload everything to dynamically pick up new stuff
    reload(modules)

    # if the module was already loaded, then we need to reload it
    for cmd in self.loadedModules.keys():
        if  self.loadedModules[cmd]['module'] == moduleName:
            modules.reload(moduleName)

    # try to grab the module and get parameters from it
    try:
        # grab the module
        m = getattr(modules, moduleName)

        # save it
        self.loadedModules[m.commandName] = {'module': moduleName, 'admin': m.adminOnly, 'version': m.version}

        # Yay it loaded :)
        retLoadedCorrectly = True

        # log it
        self.log('Loaded module: {0}, {1}, {2}, {3}'.format(moduleName, m.commandName, m.adminOnly, m.version))
    except AttributeError, e:
        self.log('Failed to load module: {0}'.format(moduleName), level='WARNING')
        self.log(e, level='WARNING')

    return retLoadedCorrectly

【讨论】:

    猜你喜欢
    • 2016-05-04
    • 1970-01-01
    • 2021-07-15
    • 2011-01-08
    • 1970-01-01
    • 2019-02-10
    • 2012-11-05
    • 2011-01-01
    • 1970-01-01
    相关资源
    最近更新 更多