我有一个烧瓶应用程序,其根文件夹名为::
。
此project_folder
软件包的__init__.py
文件中的代码段:
project_folder
现在有趣的是,@jwt.token_in_blacklist_loader
def check_if_token_in_blacklist(decrypted_token):
jti = decrypted_token['jti']
return project_folder.Model.RevokedTokenModel.is_jti_blacklisted(jti)
from project_folder.Controller.root import root
from project_folder.Controller import auth_controller
from project_folder.Controller import item_controller
包本身自然具有其他较小的包,我将其导入以使用它们(在此示例中为REST资源使用)。这是最后三行,到目前为止没有任何错误。
但是,如果您看一下带注释的函数(在此示例中,该函数始终在使用某种JWT Token之前运行),那么我将返回某些内部包的函数。现在,当逻辑真正运行此部分时,代码将中断:
project_folder
考虑之后,这似乎是可以理解的。从PROJECT_ROUTE\project_folder\__init__.py", line 38, in check_if_token_in_blacklist
return project_folder.Model.RevokedTokenModel.is_jti_blacklisted(jti)
NameError: name 'project_folder' is not defined
导入的确从包的project_folder
文件导入,该文件是解释程序当前所在的实际文件。因此,从
__init__.py
到
return project_folder.Model.RevokedTokenModel.is_jti_blacklisted(jti)
不再抛出错误。
问题是:为什么这只是回调函数内部的一个问题,而不是最后3个导入的问题?
答案 0 :(得分:1)
这与python中的循环导入有关。循环导入是循环依赖的一种形式,在模块导入级别创建。
工作原理:
启动应用程序时,python保留一个寄存器(一种表),在其中记录所有导入的模块。当您在代码中的某个位置调用模块时,python将在其注册表中查看是否已注册并从那里加载它。您可以通过sys.module
访问此注册表,该注册表实际上是dictionary
,其中包含自启动Python以来已导入的所有模块。
使用示例:
>>> import sys
>>> print('\n'.join(sys.modules.keys()))
因此,由于Python是一种解释型语言,因此代码的读取和执行是从上到下逐行进行的。
在代码中,将导入内容放在__init__.py
文件的底部。
浏览时,当python到达行return project_folder.Model.RevokedTokenModel.is_jti_blacklisted(jti)
时,它将查看模块是否在其寄存器中。显然情况并非如此。这就是为什么他引发一个NameError: name 'project_folder' is not defined
异常。