Python导入语句中使用相对路径是否有意义?

5

我有一个名为Util的Python包。它包括一堆文件。这里是其中一个文件顶部的include语句:

from config_util import ConfigUtil #ConfigUtil is a class inside the config_util module
import error_helper as eh

当我运行单元测试时,这个很好用。

但是当我在另一个包的虚拟环境中安装 Util 时,一切都崩溃了。我需要改变导入语句为

from Util.config_util import ConfigUtil
from Util import error_helper as eh

然后一切都像以前一样运作。那么使用第一种形式是否有意义,还是说总是使用第二种形式更好呢?

如果没有使用第一种形式的意义,为什么允许使用它呢?


2
您已经标记了python-3.x,但是在使用隐式相对导入。这种方式在Python 3中已被删除。我猜测您正在运行[python Util/foo.py]进行测试,而不是运行python -m Util.foo - anthony sottile
2个回答

1

错误的:

from config_util import ConfigUtil
import error_helper as eh

只有当您恰好在目录Util中时,它才能工作,以便导入可以在当前工作目录中解析。或者您使用了某些不良的黑客手段来搞乱sys.path

正确的方式(使用绝对导入):

from Util.config_util import ConfigUtil
import Util.error_helper as eh

同样正确的写法(使用相对导入):
from .config_util import ConfigUtil
import .error_helper as eh

使用相对导入没有特别的优势,只有我能想到的一些小事情:

  • 在源文件中节省了一些字节(那又怎样/谁在乎?)
  • 使您能够重命名顶级而不必编辑源代码中的导入语句(...但是您有多经常这样做?)

重命名...作为转向Python 3的一部分,我刚刚这样做了,并移动到了全绝对路径。使用了很多sed。特别是相对路径方面,它们的导入路径模式比绝对导入更难以定位,因此处理起来更加困难。顺便说一下,我最终将许多'import top.x.y.z'转换为'from top.x.y import z'。这种方式使代码更短,并且具有一定的未来重命名隔离性。 - JL Peyret

0

对于你的实际问题,也许这个答案可以帮到你。

关于你的直接问题:它们并没有太多的差别,但它们能更轻松地移动文件和重命名所包含的目录。出于风格上的原因,您可能更喜欢使用相对导入;我确实这样做。

如果路径正确,则语义是相同的。如果您的模块是foo.bar,那么from foo.bar.baz import Bazfrom .baz import Baz是相同的。如果它们没有执行相同的操作,那么你很可能正在将你的Python文件作为脚本调用(python foo/bar.py),在这种情况下它将成为模块__main__而不是foo.bar


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接