我正在使用django api建立一个网站。 问题是我得到一个奇怪的导入错误。我在一个文件中有一个函数,它调用另一个文件中的另一个函数,该函数又调用第一个文件中的第三个函数。
问题出在第三个功能期间。当我尝试导入它时出现错误
cannot import deletefromS3.
下面给出了完整的堆栈跟踪
以下是两个模块的片段:
topichandler.py:
from sdbhandler.mediahandler import deleteMediaParent
def deletefromS3(itemid,folder):
itemid=folder+itemid
bucket = connect_s3()
for key in bucket:
fname=key.split(".")[0]
if(fname==itemid):
bucket.delete_key(key)
return []
def deleteTopic(itemid,parentId='NULL'):
sdb=connect()
domain= sdb.get_domain(DOMAIN)
rootitem = domain.get_item(itemid)
if(parentId=='NULL'):
query= 'select * from ' + DOMAIN + ' where itemName()="'+itemid+'"'
rs = domain.select(query)
else:
rs = [rootitem]
for item in rs:
deleteMediaParent(item.name)
deletefromS3(item.name,'topicsK2/')
domain.delete_attributes(item.name)
deleteMediaParent(rootitem.name)
deletefromS3(rootitem.name,'topicsK2/')
domain.delete_attributes(rootitem.name)
mediahandler.py:
from sdbhandler.topichandler import deletefromS3
def deleteMediaParent(parentid):
sdb=connect()
domain = sdb.get_domain(DOMAIN)
query = 'select * from '+ DOMAIN + 'where ' +FIELD_TopicID + ' = "' + parentid + '"'
rs = domain.select(query)
for item in rs:
deleteQuestionParent(item.name)
deletefromS3(item.name,'mediaK2/')
domain.delete_attributes(item.name)
有更多依赖项,但我无法发布过多的代码。 我可以不从调用方法的文件导入吗?
答案 0 :(得分:2)
导入是不可能的,因为模块必须先完成加载才能从中导入。
加载topichandler
模块后,它会尝试从deleteMediaParent
导入mediahandler
。但mediahandler
尝试从deletefromS3
导入topichandler
,这会触发另一次加载topichandler
的尝试。 Python捕获即将发生的无限循环并改为引发错误。
让我们用一个更简单的例子来看一下。这是foo.py
:
#!/usr/bin/env python2.7
x = 3
from bar import y
print x, y
这里是bar.py
:
from foo import x
y = x
出于同样的原因,这会给你带来同样的错误。
虽然最好的解决方案可能是将您的代码重组为更一致的独立模块,但有一种解决方法。您可以通过将导入移动到函数来延迟导入,如:
#!/usr/bin/env python2.7
x = 3
from bar import y
print x, y()
bar.py
:
def y():
from foo import x
return x
请注意,如果你运行它,print
实际上会被导入两次......再次,你可能最好将相关的功能移到同一个模块中。