找到“超出顶级包的尝试的相对导入”的最佳实践

时间:2019-12-11 10:13:45

标签: python exception python-import python-3.7 relative-import

我想通过在导入中已经包含异常处理来缩小常见错误"attempted relative import beyond top-level package"的范围。

DjangoProject/tests.py的Django测试中,我编写了相对于自身(tests.py)的导入。 执行每个测试文件的默认unittests.py位于root文件夹中,该文件夹还包括DjangoProject文件夹。

在添加错误代码attempted relative import beyond top-level package时, DjangoProject/tests.py try: from django.utils.safestring import mark_safe import json from django.conf import settings from viewsfunctions import * from .. import PoM import unittest except Exception as importex: print("Error in the tests.py-imports: "+str(importex)) 对我的单元测试来说很明显它来自进口。通过try / except,我能够编写一个更清晰的错误,因此无需猜测为什么和哪个文件导致了错误。

现在我的代码如下:

"No module named 'viewsfunctions'"

它首先引发了以下消息:

viewsfunctions

是有意义的,因为DjangoProjectfrom DjangoProject.viewsfunctions import *内部的一个模块,因此很有用。我将行替换为:Error in the Imports: attempted relative import beyond top-level package

下一个错误是:

from .. import PoM

这正是我的问题。这可能是任何内容。通过仅进行pdbing,我可以将其跟踪到PoM(因为模块tests.py相对于顶部文件夹中的unittests.py,而相对于执行中的toggle-left同一文件夹)

在这种情况下,只有少量导入,将其缩小范围相对较快,但是有什么方法可以编写更好的异常消息或以某种方式提供更多信息,其中错误实际上发生在哪个导入行中?

1 个答案:

答案 0 :(得分:0)

如果您只是捕获异常,那么您将获得非常有用的回溯:

>>> from .. import foo
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "/Users/deceze/...", line 21, in do_import
    module = self._system_import(name, *args, **kwargs)
ImportError: attempted relative import with no known parent package

问题是您正在捕获异常,并且仅打印可能的最小错误消息。如果您确实出于某种原因想要捕获异常,但仍收到完整的错误消息,最简单的方法是使用logging module

import logging

try:
    ...
except:
    logging.exception('Error fooing the bar')

这将产生您的自定义错误消息,然后是完整的堆栈跟踪。

要获取更多手册,请使用traceback module

import traceback

try:
    ...
except:
    print('Error fooing the bar')
    traceback.print_exc()

借助traceback中的其他功能,您可以更细粒度地从异常中打印或检索消息,只要您愿意即可。