我有两个文件rest_api.py
和Contact.py
。联系人类似于域对象(包含Contact
类),而rest_api具有设置应用程序的功能。
在rest_api
我有以下几行:
from Contact import Contact
...
client = MongoClient('localhost',27017)
collection = client.crypto_database.test_collection
def dbcollection(){
return collection
}
...
api.add_resource(Contact,'/contact/<string:contact_id>')
在Contact
中,我尝试执行以下操作:
from rest_api import dbcollection
class Contact(Resource):
def get(self,contact_id):
result = {}
result['data'] = dbcollection.find_one({'contact_id':contact_id})
result['code'] = 200 if result['data'] else 404
return make_response(dumps(result), result['code'],{"Content-type": "application/json"})
此操作失败,并显示以下错误:
ImportError: cannot import name Contact
导入联系人的正确方法是什么,以便它还可以使用rest_api中的变量/函数?
p.s如果我将收集代码移动到另一个文件,并导入该文件而不是工作,但我认为还有其他方法..
答案 0 :(得分:2)
这是循环导入依赖项,无法解决。问题是,导入python模块确实运行代码,必须遵循一些顺序,其中一个模块必须先行。
我想说将支持代码放在不同的文件中是正确的方法。
但是,在这种情况下,导入时实际上并不需要dbcollection
。因此,您可以通过从模块级别导入get函数来解决此问题。例如
class Contact(Resource):
def get(self,contact_id):
from rest_api import dbcollection
result = {}
result['data'] = dbcollection.find_one({'contact_id':contact_id})
result['code'] = 200 if result['data'] else 404
return make_response(dumps(result), result['code'],{"Content-type": "application/json"})
类似的方法如下:
import rest_api
class Contact(Resource):
def get(self,contact_id):
result = {}
result['data'] = rest_api.dbcollection.find_one({'contact_id':contact_id})
result['code'] = 200 if result['data'] else 404
return make_response(dumps(result), result['code'],{"Content-type": "application/json"})
这应该可行,因为python会努力解决循环导入依赖关系:当它开始导入模块时,它会为该模块创建一个空模块dict。然后,当它找到嵌套导入时,它将继续执行该导入。如果依次导入已经在导入过程中的模块,它只是跳过它。因此,在加载Contact.py
时,import rest_api
只接受已存在的模块字典。由于它还不包含dbcollection
,from rest_api import dbcollection
失败。然而,一个简单的import rest_api
可以正常工作,因为它的成员仅在Contact.py
完成导入后解决(除非您在模块级别从内部调用Contact.get
)。
答案 1 :(得分:0)
假设您还没有了解哪些模块将导入哪些模块,您可以自己跟踪,而不是导入。
在__init__.py中,定义这些 -
__module_imports__ = {}
def requires_module(name):
return name not in __module_imports__
def importing_module(name):
__module_imports__[name] = True
然后,在每个类文件的顶部,您定义类的位置,将以下内容添加到this_module.py:
from my_modules import requires_module, importing_module
importing('ThisModule')
if requires_module('ThatModule')
from my_modules.that_module import ThatModule
class ThisModule:
""" Real Stuff Goes Here """
pass
和this_module.py:
from my_modules import requires_module, importing_module
importing('ThatModule')
if requires_module('ThisModule')
from my_modules.this_module import ThisModule
class ThatModule:
""" Real Stuff Goes Here """
pass
现在你可以获得你的导入,无论先导入哪些导入或其他任何导入。