【问题标题】:How to dynamiclly import changing module?如何动态导入变化的模块?
【发布时间】:2014-08-24 06:57:41
【问题描述】:

第 1 步:假设这是更改模块,名为 test_module.py

#coding=utf8
# changing module    

class hello(object):
    pass


"""
class world(object):
    pass
"""

第二步:动态重新加载changing module,命名为dynamis_sharing_import.py

"""
@note: Dynamicly import changing module
"""

__author__ = 'k9 Lee'


import sys
import importlib


"""
@important: Does not consider thread safty
"""

def dy_import(name, package=None):
    # Fast path: see if the module has already been imported.
    # @doc: imp
    try:
        sys.modules[name]
    except KeyError:
        # if not found, just import
        importlib.import_module(name, package)
    else:
        # del and reload module
        print '1'
        del sys.modules[name]
        print '2'
        #importlib.import_module(name, package)
        #print '3'

第 3 步:在 ipython 中测试,

然后我发现sys.modules['test_module'] raise key 错误,这意味着我可以重新导入 test_module,

但我仍然可以dir(test_module)...

In [1]: import test_module

In [2]: dir(test_module)
Out[2]: ['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'hello']

In [3]: import dynamis_changing_import

In [4]: dynamis_changing_import.dy_import('test_module')
1
2

In [5]: import sys

In [6]: sys.modules['test_module']  # Here, test_module does not exist.
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-6-d2451de5c425> in <module>()
----> 1 sys.modules['test_module']

KeyError: 'test_module'

In [7]: dir(test_module)  # But... dir... is still there...
Out[7]: ['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'hello']

第 4 步。仍然测试 ipython: 我取消注释文件dynamis_changing_import.py 中的最后两条语句,

importlib.import_module(name, package)
print '3'

importlib.import_module没有效果,我重启ipython:

In [1]: import sys

In [2]: import dynamis_changing_import

In [3]: import test_module

In [4]: dir(test_module)
Out[4]: ['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'hello']

In [5]: # Uncomment the method `world` in test_module

In [6]: dynamis_changing_import.dy_import('test_module')
1
2
3

In [7]: dir(test_module)
Out[7]: ['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'hello']

谢谢。

【问题讨论】:

  • 模块如何以及为什么会发生变化?
  • 您需要将importlib.import_module(name, package)返回的模块重新分配给test_module,否则您只是在丢弃新的模块对象。您也可以使用reload() 重新加载模块。

标签: python import dir


【解决方案1】:

不要惹sys.modules。这是一个非常底层的细节。

要安全地重新加载模块,您可以简单地:

对于跨版本解决方案,只需执行以下操作:

import sys
if sys.version_info.major == 3:
    if sys.version_info.minor < 4:
        from imp import reload
    else:
        from importlib import reload

当您想重新导入模块 X 时,您只需这样做:

reload(X)

所以“动态导入”就变成了:

import moduleX

每当您需要重新加载模块时,您都可以这样做:

reload(moduleX)

示例运行:

$ echo 'def f():print("a")
> f()' > t.py
$ python2
>>> import t
a
>>> t.f()
a
# in an other shell:
# $ echo 'def f():print("b")
# > f()' > t.py
>>> reload(t)
b
>>> t.f()
b

【讨论】:

    猜你喜欢
    • 2017-07-13
    • 1970-01-01
    • 1970-01-01
    • 2022-12-11
    • 2016-08-15
    • 2020-07-25
    • 2011-04-17
    • 2023-02-01
    • 2011-04-06
    相关资源
    最近更新 更多