我有一个名为Contemplate的模板引擎,它具有node/js
,python
和ModuleNotFoundError: 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秒,但是有时在首次创建模板之前将其导入也会引起相同的错误。有解决方案吗?
答案 0 :(得分:1)
对,如果您使用“ while”循环来处理异常将是一种方法。
while True:
try:
#The module importing
break
except ModuleNotFoundError:
print("NOPE! Module not found")
如果它适用于其他文件,而不是其他“模块”文件,则可能是模板文件本身就是模板文件。