在主模块中启用显式相对导入。
rel_imp的Python项目详细描述
以简单的方式在主模块中启用显式相对导入。
为了在__main__module pep 366中启用相对导入,提供了 解决方法如下:
if__name__=="__main__"and__package__isNone:__package__="my_pkg"from.fooimportbar
使用rel_imp您可以将其重写为:
importrel_imp;rel_imp.init()from.fooimportbar
更干净,更快,更少耦合。(不需要指定包 手动)
注意:要使用rel_imp,您正在编码的模块必须是 在包或子包中。
为什么使用显式相对导入?
python 2仍然支持隐式相对导入,并且将被弃用。 在python 3中,您将希望使用隐式 相对导入到显式相对导入。查看PEP 404上的更多信息。
显式的相对导入会减少代码的耦合。作为PEP 328 说:
Several use cases were presented, the most important of which is being able to rearrange the structure of large packages without having to edit sub-packages. In addition, a module inside a package can’t easily import itself without relative imports.
尽管这仍然是一个品味的问题。(我个人更喜欢较少的代码 表示相同)
为什么以子模块为主运行?
一些原因:
- 如果作为main调用,子模块可以成为命令行工具。
- 您可以在模块内进行单元测试或冒烟测试。
- 你只想在没有任何显式测试的情况下运行它,看看 至少它需要进口所有东西。
安装和卸载
通过PIP安装
pip install rel_imp
使用以下命令将其删除:
pip uninstall rel_imp
安装并下载文件
在python的搜索路径中下载rel_imp.py。
wget https://raw.githubusercontent.com/joaduo/rel_imp/master/rel_imp.py
示例
假设您在一个名为“my_pkg”的包中有两个模块。
那就是:
- my_pkg/__init__.py
- my_pkg/math_lib.py
- my_pkg/test.py
所以在test.py中我们可以有
from.math_libimportfactorizedeffactorize_and_print(number):num=factorize(number)printnumif__name__=='__main__':#Small smoke testfactorize_and_print(10)factorize_and_print(0)factorize_and_print(-10)
如果这样做python my_pkg/test.py,它将抛出异常,因为 在第一行的相对导入。
所以可以使用rel_imp使代码看起来更好。简单地做:
importrel_imp;rel_imp.init()from.math_libimportfactorize
它相当于先前的解决方案,但您不必担心 保持同步__package__的值。
它是如何工作的?
它在pep 366中使用相同的技术,但是设置了__package__的值 通过对烟囱的动态检测。解决 __package__它将当前的__main__文件与搜索进行比较 sys.path中的路径-或者,可选地,在 设置-。
例如,对于 /home/user/projects/python/math/my_pkg/test.py给定以下条件 sys.path中的路径:
['/home/user/projects/python/','/home/user/projects/python/math/','/home/user/projects/python/math/my_pkg/',]
它将选择距__main__文件最近的路径,该文件不是 __main__的文件目录。
然后用于求解__package__变量的基路径将是 /home/user/projects/python/math/
禁用rel_imp
相对导入不应该有任何不期望的副作用,但是如果 您想禁用它的某些原因:
- 替换rel_imp.py文件中的def init()函数(如果 你下载的)
- 在一个 优先级高于已安装的pythonpath(或可选 卸载原始版本)
rel_imp非常轻量级,因此不会获得任何性能 差异禁用它。