[python] 包管理


最近感觉得把之前的一些知识做下总结, 后面将一块内容以可以清楚表述为标准进行判断是否掌握

python 包管理个人感觉是包含PEP382[1](PEP420[2]中完善)为分界的两个版本

第一版,在PEP382之前,主要的包管理模式为 [常规包] 形式, 主要特征为默认包含 __init__.py 文件作为一个python包

第二版,在PEP420之后,[命名空间包]相对成熟, 支持模块导入 (PEP382就开始支持, 但是PEP420之后功能完善), 特征为支持 -m 参数作为模块导入

个人认为 命名空间包 的主要优势在于支持相对导入 见下面文件结构

 1 text = "print(f'__name__: {__name__}, __file__: {__file__}, __package__: {repr(__package__)}')"
 2 
 3 from pathlib import Path
 4 Path('foo.py').write_text(text)
 5 Path('package').mkdir()
 6 Path('package/__init__.py').write_text(text)
 7 Path('package/__main__.py').write_text(text)
 8 Path('package/bar.py').write_text(text)
 9 
10 # and include a submodule with a relative import:
11 Path('package/baz.py').write_text(text + '\nfrom . import bar')

分别在最外层以两种模式实验运行baz.py模块

在包含__init__.py文件时, 两种情况可以实现相同功能

python3 package/baz.py
'''
__main__, __file__: package/baz.py, __package__: None
Traceback (most recent call last):
  File "package/baz.py", line 5, in <module>
    from package import bar
ModuleNotFoundError: No module named 'package'
'''

python3 -m package.baz
'''
package, __file__: /data/path/package/__init__.py, __package__: 'package'
__main__, __file__: /data/path/package/baz.py, __package__: 'package'
package.bar, __file__: /data/path/package/bar.py, __package__: 'package'
'''

可以看到第一种模式出错了, 这主要是因为package这个模块不在sys.path中,我们可以将其设为 sys.path的第一个值 来成功运行, 添加如下代码, 可以看到其顺利运行了,

之前我这边的老脚本都是这种机制实现的

import os
import sys
if __name__ == '__main__':
    sys.path.insert(0, os.path.abspath(os.curdir))


python3 package/baz.py
__main__, __file__: package/baz.py, __package__: None
package, __file__: /data/path/package/__init__.py, __package__: 'package'
package.bar, __file__: /data/path/package/bar.py, __package__: 'package'

如今基于 -m 的命名空间包 机制, 省去的这个麻烦

下面讲下__main__.py文件,

见上方 模块运行的例子, 可以看到虽然先调用了 package/__init__.py文件, 但是在调用package/baz.py的时候其才是__main__, 所以可以判断__name__ == "__main__"

那么__main__.py什么时候运行呢, 答案是通过 python -m package 的时候, 会在__init__.py 运行之后运行,基于这种机制, 以后可以创建__main__.py文件,整个脚本代码更为简洁,(少了判断)

以后有空讲讲 __import__, import_module, 第三方库如何实现自定义的文件加载这些内容

[1]PEP382:https://www.python.org/dev/peps/pep-0382/

[2]PEP420:https://www.python.org/dev/peps/pep-0420/

优质内容筛选与推荐>>
1、高性能Android应用开发
2、linux下进程编程综述
3、Android Eclipse真机调试 过滤器filter没有显示
4、第三周课程总结及实验报告
5、Spring 框架的架包分析、功能作用、优点,及jar架包简介


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号





    联系我们

    欢迎来到TinyMind。

    关于TinyMind的内容或商务合作、网站建议,举报不良信息等均可联系我们。

    TinyMind客服邮箱:support@tinymind.net.cn