Python:动态导入的模块在首次创建时失败,然后成功

时间:2019-01-18 13:24:23

标签: python-3.x dynamic python-import

我有一个名为Contemplate的模板引擎,它具有node/jspythonModuleNotFoundError: No module named 'blah blah'的实现。

除了最近的python实现给我一些问题外,其他所有工作都很好。具体来说,当首先解析模板并创建模板python代码,然后将其动态导入为模块时,就会出现此问题。当已经创建模板时,一切正常,但是当需要解析模板并将其保存到磁盘并随后导入时,会引发错误,例如

def import_tpl( filename, classname, cacheDir, doReload=False ): # http://www.php2python.com/wiki/function.import_tpl/ # http://docs.python.org/dev/3.0/whatsnew/3.0.html # http://stackoverflow.com/questions/4821104/python-dynamic-instantiation-from-string-name-of-a-class-in-dynamically-imported #_locals_ = {'Contemplate': Contemplate} #_globals_ = {'Contemplate': Contemplate} #if 'execfile' in globals(): # # Python 2.x # execfile(filename, _globals_, _locals_) # return _locals_[classname] #else: # # Python 3.x # exec(read_file(filename), _globals_, _locals_) # return _locals_[classname] # http://docs.python.org/2/library/imp.html # http://docs.python.org/2/library/functions.html#__import__ # http://docs.python.org/3/library/functions.html#__import__ # http://stackoverflow.com/questions/301134/dynamic-module-import-in-python # http://stackoverflow.com/questions/11108628/python-dynamic-from-import # also: http://code.activestate.com/recipes/473888-lazy-module-imports/ # using import instead of execfile, usually takes advantage of Python cached compiled code global _G getTplClass = None # add the dynamic import path to sys basename = os.path.basename(filename) directory = os.path.dirname(filename) os.sys.path.append(cacheDir) os.sys.path.append(directory) currentcwd = os.getcwd() os.chdir(directory) # change working directory so we know import will work if os.path.exists(filename): modname = basename[:-3] # remove .py extension mod = __import__(modname) if doReload: reload(mod) # Might be out of date # a trick in-order to pass the Contemplate super-class in a cross-module way getTplClass = getattr( mod, '__getTplClass__' ) # restore current dir os.chdir(currentcwd) # remove the dynamic import path from sys del os.sys.path[-1] del os.sys.path[-1] # return the tplClass if found if getTplClass: return getTplClass(Contemplate) return None

注意),此错误似乎是随机的,并非总是可以确定会发生此错误,即使导入之前创建了模板,该错误也会多次起作用,而其他时候则失败,然后使用已创建的模板再次运行,则成功)

有什么办法可以绕过这个问题,也许在保存已解析的模板与作为模块或其他东西导入之间增加了延迟?

下面是导入模块的代码(已解析的模板,现在是python类):

__init__.py

注意(如果该文件尚不存在,则引擎会在cacheDir中创建一个import_tpl文件)。

如果需要,我可以将python 3.6函数更改为其他我不介意的地方。

经过测试的Python是windows上的github,但我不认为这是特定于平台的问题。

要测试该问题,可以从/tests/test.py文件夹中清除所有缓存的模板后,下载/tests/_tplcache/存储库(上面链接)并运行while测试

更新:

我正在考虑在import_tpl中添加一个带有一些计数器的{{1}}循环,以捕获出现的错误并重试指定的时间,直到成功导入模块。但是我也想知道这是否是一个好的解决方案,或者我在这里还缺少其他东西。

更新(20/02/2019):

添加了一个循环,以重试指定的时间,如果最初导入模板模块失败(请参见在线存储库代码),则延迟1秒,但是有时在首次创建模板之前将其导入也会引起相同的错误。有解决方案吗?

1 个答案:

答案 0 :(得分:1)

对,如果您使用“ while”循环来处理异常将是一种方法。

while True:
    try:
        #The module importing
        break
    except ModuleNotFoundError:
        print("NOPE! Module not found")

如果它适用于其他文件,而不是其他“模块”文件,则可能是模板文件本身就是模板文件。