|涨见识了,在终端执行 Python 代码的 6 种方式( 二 )
本文插图
目录
定义__main__.py也可以扩展到目录 。 如果你看一下促成此博客文章的示例 , python news可执行 , 就是因为 news 目录有一个__main__.py文件 。 该目录就像一个文件路径被 Python 执行了 。
本文插图
img
现在你可能会问:“为什么不直接指定文件路径呢?”好吧 , 坦白说 , 关于文件路径 , 有件事得说清楚 。 ??在发布过程中 , 我可以简单地写上说明 , 让运行python news/announce.py , 但是并没有确切的理由说明这种机制何时存在 。
再加上我以后可以更改文件名 , 而且没人会注意到 。 再加上我知道代码会带有辅助文件 , 因此将其放在目录中而不是单独作为单个文件是有意义的 。
当然 , 我也可以将它变为一个使用 -m 的包 , 但是没必要 , 因为 announce 脚本很简单 , 我知道它要保持成为一个单独的自足的文件(少于 200 行 , 并且测试模块也大约是相同的长度)
况且 , __main__.py文件非常简单 。
import runpy
# Change 'announce' to whatever module you want to run.
runpy.run_module('announce', run_name='__main__', alter_sys=True)
现在显然必须要处理依赖关系 , 但是如果你的脚本仅使用标准库或将依赖模块放在__main__.py旁边(译注:即同级目录) , 那么就足够了!
(译注:我觉得作者在此有点“炫技”了 , 因为这种写法的前提是得知道 runpy 的用法 , 但是就像前一条所写的用 -m 参数运行一个包 , 在底层也是用了 runpy 。 不过炫技的好处也非常明显 , 即__main__.py里不用导入 announce 模块 , 还是以它为主模块执行 , 也就不会破坏原来的依赖导入关系)
本文插图
执行一个压缩文件
如果你确实有多个文件和/或依赖模块 , 并且希望将所有代码作为一个单元发布 , 你可以用一个__main__.py , 放置在一个压缩文件中 , 并把压缩文件所在目录放在 sys.path 里 , Python 会替你运行__main__.py文件 。
# 将一个压缩包传给 Python
python app.pyz
人们现在习惯上用 .pyz 文件扩展名来命名此类压缩文件 , 但这纯粹是传统 , 不会影响任何东西;你当然也可以用 .zip 文件扩展名 。
为了简化创建此类可执行的压缩文件 , 标准库提供了zipapp[7]模块 。 它会为你生成__main__.py并添加一条组织行(shebang line) , 因此你甚至不需要指定 python , 如果你不想在 UNIX 上指定它的话 。 如果你想移动一堆纯 Python 代码 , 这是一种不错的方法 。
不幸的是 , 仅当压缩文件包含的所有代码都是纯 Python 时 , 才能这样运行压缩文件 。 执行压缩文件对扩展模块无效(这就是为什么 setuptools 有一个 zip_safe[8]标志的原因) 。 (译注:扩展模块 extension module , 即 C/C++ 之类的非 Python 文件)
要加载扩展模块 , Python 必须调用 dlopen[9]函数 , 它要传入一个文件路径 , 但当该文件路径就包含在压缩文件内时 , 这显然不起作用 。
我知道至少有一个人与 glibc 团队交谈过 , 关于支持将内存缓冲区传入压缩文件 , 以便 Python 可以将扩展模块读入内存 , 并将其传给压缩文件 , 但是如果内存为此服务 , glibc 团队并不同意 。
但是 , 并非所有希望都丧失了!你可以使用诸如shiv[10]之类的项目 , 它会捆绑(bundle)你的代码 , 然后提供一个__main__.py来处理压缩文件的提取、缓存 , 然后为你执行代码 。 尽管不如纯 Python 解决方案理想 , 但它确实可行 , 并且在这种情况下算得上是优雅的 。
推荐阅读
- 摄影|传音主导首个移动终端计算摄影系统国际标准获ITU-T正式立项
- 自动驾驶|AutoX获第二张加州全无人驾驶牌照;乐视控股被列为被执行人 | 晚报
- 手电|滴滴重启顺风车,专家建议女白领勿穿黑丝上夜班,网友:见识短浅
- 群众网|滴滴重启顺风车,专家建议女白领勿穿黑丝上夜班,网友:见识短浅
- 行业互联网|海信关联公司成被执行人,执行标的超20万元
- 机动车|北京人人车旧机动车经纪公司成被执行人 执行标的超104万
- 新浪网|北京人人车旧机动车经纪公司成被执行人 执行标的超104万
- |Avaya Open SIP智能终端,您智慧沟通的不二之选
- 充电器|OPPO 发布125W超级闪充技术,未来布局多终端、多场景闪充生态
- 科学探索|如果人类以2千倍的光速飞行,多久可以穿越银河系?看完长见识了
