Python import中相对路径的问题
博客专区 > Honghe 的博客 > 博客详情
Python import中相对路径的问题
Honghe 发表于5年前
Python import中相对路径的问题
  • 发表于 5年前
  • 阅读 22779
  • 收藏 4
  • 点赞 0
  • 评论 0

腾讯云 学生专属云服务套餐 10元起购>>>   

1. 从查到的资料来看,关于import路径的来说,分成3类:
  • absolute import 
import xml
import youpackage.xml
from youpackage import xml
这几种都算绝对路径

  • relative import
import xml
从这个语句上是看不出来import的是标准库的xml,还是你的包里的一个库叫xml。

  • explicit relative import
from . import xml
from .xml import some_thing
from ..xml import some_thing
这些以点开头的import明确的表示了import的是相对路径,从而避免了普通relative import的麻烦。

2. 第二种(relative import)肯定是不推荐的。
  • 在python2.5以前,如果当前包中有一个叫xml的库,局部的这个xml就会shadow标准库的xml(和局部变量感觉类似,我犯过好几次这个错误,调试的时候还一定能反应过来)。
  • 在2.5和2.6,这个行为还是一样的,但是如果有以下这个语句,局部的包将不能覆盖全局的包
from __future__ import absolute_import
  • 在2.7中,absolute_import的行为变成了默认行为,如果需要应用局部的包,那就得用明确的相对引用了。
文档是这么描述的,但通过-m运行和直接运行py的行为还是会不一样,看下面这个例子:
$ python --version
Python 2.6.5

$ cat bar/baz.py 
from __future__ import absolute_import
import xml
print xml.__file__

$ python bar/baz.py 
/home/huanghao/workspace/test/bar/xml.pyc

$ python -m bar.baz
/usr/lib/python2.6/xml/__init__.pyc

看上去很奇怪,通过py运行的时候absolute_import好像根本没有作用,原因在这个blog里有解释

3.所以说relative import麻烦事太多,一定不能用了。但是absolute和explicit relative这两个到底用哪个?
PEP8中提到:
Relative imports for intra-package imports are highly discouraged. Always use the absolute package path for all imports. Even now that  PEP 328  is fully implemented in Python 2.5, its style of explicit relative imports is actively discouraged; absolute imports are more portable and usually more readable.

PEP8还是建议用absolute,即使PEP328实现了explicit relative。
本来我觉得到此就为止了。 但是今天还是有同事非要用explicit relative import,跟我说因为absolute写起来太长,而且当顶层包重命名时,所有的文件都需要修改。
我搜了半天也没找到有文章提到abs比rel一定要好的理由,除了PEP8提到的两个缺乏说服力的词more portable and more readable。
4.explicit relative import有一个小问题:
Relative imports use a module's __name__ attribute to determine that module's position in the package hierarchy. If the module's name does not contain any package information (e.g. it is set to '__main__') then relative imports are resolved as if the module were a top level module, regardless of where the module is actually located on the file system.

Note that both explicit and implicit relative imports are based on the name of the current module. Since the name of the main module is always "__main__" , modules intended for use as the main module of a Python application should always use absolute imports.

PEP 338 -- Executing modules as scripts:  http://www.python.org/dev/peps/pep-0338/

虽然PEP338搞定了explicit relative import 在-m执行时的问题,但是搞不定直接文件执行的情况。所以用来做程序入口的模块必须使用绝对引用。
看一下这个例子:
$ python --version
Python 2.6.5

$ cat bar/baz.py 
from . import xml
print xml.__file__

$ python -m bar.baz
bar/xml.pyc

$ python bar/baz.py 
Traceback (most recent call last):
  File "bar/baz.py", line 1, in <module>
    from . import xml
ValueError: Attempted relative import in non-package

共有 人打赏支持
Honghe
粉丝 57
博文 125
码字总数 35339
作品 3
×
Honghe
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: