使用python和Django时导入错误

时间:2013-07-04 20:14:34

标签: python django

我正在使用django api建立一个网站。 问题是我得到一个奇怪的导入错误。我在一个文件中有一个函数,它调用另一个文件中的另一个函数,该函数又调用第一个文件中的第三个函数。

问题出在第三个功能期间。当我尝试导入它时出现错误

cannot import deletefromS3.

下面给出了完整的堆栈跟踪

http://dpaste.com/1288190/

以下是两个模块的片段:

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)

有更多依赖项,但我无法发布过多的代码。 我可以不从调用方法的文件导入吗?

1 个答案:

答案 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实际上会被导入两次......再次,你可能最好将相关的功能移到同一个模块中。