在终端执行 Python 代码的 6 种方法,原来还能这样!
来自 | Python猫 编译 | 豌豆花下猫
原作 | BRETT CANNON
为了我们推出的 VS Code 的 Python 插件[1],我写了一个简单的脚本来生成变更日志[2](类似于Towncrier[3],但简单些,支持 Markdown,符合我们的需求)。在发布过程中,有一个步骤是运行python news
,它会将 Python 指向我们代码中的"news"目录。
前几天,一位合作者问这是如何工作的,似乎我们团队中的每个人都知道如何使用-m
?请参阅我的有关带 -m 使用 pip 的文章[4],了解原因。
这使我意识到其他人可能不知道有五花八门的方法可以将 Python 指向要执行的代码,因此有了这篇文章。
1、通过标准输入和管道
因为如何用管道传东西给一个进程是属于 shell 的内容,我不打算深入解释。毋庸置疑,你可以将代码传递到 Python 中。
# 管道传内容给 python
echo "print('hi')" | python
如果将文件重定向到 Python,这显然也可以。
# 重定向一个文件给 python
python < spam.py
归功于 Python 的 UNIX 传统,这些都不太令人感到意外。
2、通过 -c 指定的字符串
如果你只需要快速地检查某些内容,则可以在命令行中将代码作为字符串传递。
# 使用 python 的 -c 参数
python -c "print('hi')"
当需要检查仅一行或两行代码时,我个人会使用它,而不是启动 REPL(译注:Read Eval Print Loop,即交互式解释器,例如在 windows 控制台中输入python
, 就会进入交互式解释器。-c 参数用法可以省去进入解释器界面的过程)
3、文件的路径
最众所周知的传代码给 python 的方法很可能是通过文件路径。
# 指定 python 的文件路径
python spam.py
要实现这一点的关键是将包含该文件的目录放到sys.path
里。这样你的所有导入都可以继续使用。但这也是为什么你不能/不应该传入包含在一个包里的模块路径。因为sys.path
可能不包含该包的目录,因此所有的导入将相对于与你预期的包不同的目录。
4、对包使用 -m
执行 Python 包的正确方法是使用 -m 并指定要运行的包名。
python -m spam
它在底层使用了runpy[5]。要在你的项目中做到这点,只需要在包里指定一个__main__.py
文件,它将被当成__main__
执行。而且子模块可以像任何其它模块一样导入,因此你可以对其进行各种测试。
我知道有些人喜欢在一个包里写一个main
子模块,然后将其__main__.py
写成:
from . import mainif __name__ == "__main__":main.main()
就我个人而言,我不感冒于单独的main
模块,而是直接将所有相关的代码放入__main__.py
,因为我感觉这些模块名是多余的。
(译注:即作者不关心作为入口文件的"main"或者“__main__”模块,因为执行时只需用它们的包名即可。我认为这也暗示了入口模块不该再被其它模块 import。)
5、目录
定义__main__.py
也可以扩展到目录。如果你看一下促成此博客文章的示例,python news
可执行,就是因为 news 目录有一个 __main__.py
文件。该目录就像一个文件路径被 Python 执行了。
现在你可能会问:“为什么不直接指定文件路径呢?”好吧,坦白说,关于文件路径,有件事得说清楚。在发布过程中,我可以简单地写上说明,让运行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 模块,还是以它为主模块执行,也就不会破坏原来的依赖导入关系)
6、执行一个压缩文件
如果你确实有多个文件和/或依赖模块,并且希望将所有代码作为一个单元发布,你可以用一个__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 解决方案理想,但它确实可行,并且在这种情况下算得上是优雅的。
参考链接
[0] https://snarky.ca/the-many-ways-to-pass-code-to-python-from-the-terminal/
[1] https://marketplace.visualstudio.com/items?itemName=ms-python.python
[2] https://github.com/microsoft/vscode-python/tree/master/news
[3] https://pypi.org/project/towncrier
[4] https://snarky.ca/why-you-should-use-python-m-pip
[5] https://docs.python.org/3/library/runpy.html#module-runpy
[6] https://mp.weixin.qq.com/s/1ehySR5NH2v1U8WIlXflEQ
[7] https://docs.python.org/3/library/zipapp.html#module-zipapp
[8] https://setuptools.readthedocs.io/en/latest/setuptools.html#setting-the-zip-safe-flag
[9] https://linux.die.net/man/3/dlopen
[10] https://pypi.org/project/shiv
原文链接:
https://snarky.ca/the-many-ways-to-pass-code-to-python-from-the-terminal
精 彩 文 章
干货!隐马尔科夫模型
牛逼!用 AI 实现 C++、Java、Python 代码互译!
真香!一行Python代码,帮你制作小姐姐的表情包,靠谱吗?
END
最后说个题外话,相信大家都知道视频号了,随着灰度范围扩大,越来越多的小伙伴都开通了视频号。小詹也开通了一个视频号,会分享互联网那些事、读书心得与副业经验,欢迎扫码关注,和小詹一起向上生长!「没有开通发布权限的尽量多互动,提升活跃度可以更快开通哦」
在终端执行 Python 代码的 6 种方法,原来还能这样!相关推荐
- 涨见识了,在终端执行 Python 代码的 6 种方式
作者 | BRETT CANNON 译者 | 豌豆花下猫@Python猫 为了我们推出的 VS Code 的 Python 插件[1],我写了一个简单的脚本来生成变更日志[2](类似于Towncrie ...
- python交互式方式、代码文件方式_涨见识了,在终端执行 Python 代码的 6 种方式
原作:BRETT CANNON 译者:豌豆花下猫@Python猫 英文:https://snarky.ca/the-many-ways-to-pass-code-to-python-from-the- ...
- python花猫_涨见识了,在终端执行 Python 代码的 6 种方式!
原作: BRETT CANNON 译者:豌豆花下猫@Python猫 英文: https://snarky.ca/the-many-ways-to-pass-code-to-python-from-th ...
- 执行python代码的方式_涨见识了,在终端执行 Python 代码的 6 种方式!
译者:豌豆花下猫@Python猫 为了我们推出的 VS Code 的 Python 插件 [1],我写了一个简单的脚本来生成变更日志 [2](类似于Towncrier [3],但简单些,支持 Mark ...
- 加密Python代码的5种方法
Python越来越热门了,2022年1月编程语言排行榜上挤进第一. Python优点很多,比如简单易学,代码量少,能做的事很多等等,和其他语言一样,Python也有一些不可掩盖的缺点,版本不兼容,运行 ...
- pca算法python代码_三种方法实现PCA算法(Python)
主成分分析,即Principal Component Analysis(PCA),是多元统计中的重要内容,也广泛应用于机器学习和其它领域.它的主要作用是对高维数据进行降维.PCA把原先的n个特征用数目 ...
- 优化Python代码的4种方法
介绍 作为数据科学家,编写优化的Python代码非常非常重要.杂乱,效率低下的代码即浪费你的时间甚至浪费你项目的钱.经验丰富的数据科学家和专业人员都知道,当我们与客户合作时,杂乱的代码是不可接受的. ...
- 【Java后台】Java执行Python代码的3类5种情况测试【Java源码+Python源码举例】
1.why python拥有的某些库要比Java强大,也拥有一些比Java更擅长的领域,python可以搭建后端让Java调用接口,但某些时候我们用到的python代码可能并不多也许只有一个算法,此时 ...
- Pycharm中运行Python代码的几种方式
Pycharm中运行Python代码的几种方式 在pycharm中的Python代码运行会出现各种奇葩的问题,比如,密码输入时不显示或没有提示,给我们带来一些麻烦,下面介绍几种代码运行的几种方式: 一 ...
最新文章
- mysql galera_(十六)MySQL集群galera实现
- Windows登录类型知多少?
- JVM【带着问题去学习 01】什么是JVM+内存结构+堆内存+堆内存参数(逃逸分析)
- 看不懂简明python教程_简明python教程之Python文件头注释的含义,你肯定不懂
- 视频剪辑软件对比之:会声会影与剪映
- Item 22. 模板方法与曲线救国(Template Method)
- 去除点击链接时出现的虚线框
- 绿联USB2.0 USB外接网卡驱动
- r语言如何计算t分布临界值_「SPSS数据分析」SPSS差异分析(3)独立样本T检验操作步骤及解读...
- 二十四小时不插电生活方案
- 手机居然可以变成电脑的无线麦克风?快来瞧瞧
- 树莓派控制4路5v继电器开关
- 荣联再次中标中国移动云资源池项目
- Win11老是弹出输入体验怎么办
- 【vue eslint】报错Component name “xxxxx“ should always be multi-word.eslintvue/四种解决方案
- postgresql 遍历参数_《go语言从入门到入坟》json操作、文件操作
- 众昂矿业:萤石货源紧张,价格可能上涨
- ubuntu16.04 离线deb包 安装vim 离线环境
- 《天才基本法》中的P=NP?问题对应算法逻辑
- R语言解决package ‘MODIS’ is not available (for R version 3.6.3) 的问题
热门文章
- PHP中间件ICE,ICE的安装配置,ICE常见编译和运行(异常)错误(自测Php版本安装部分,因为php版本跟ice版本不一样失败)
- 总结PHP中DateTime的常用方法
- PHP调用JS/CSS方法
- java+cache使用方法_java相关:Spring boot redis cache的key的使用方法
- centos7 防火墙_Linux系统安全Centos 7的Firewalld防火墙基础
- CRMEB删除公众号首页logo动画
- windows linux 融合,Windows和Linux的设备驱动框架的对比融合研究
- ironpython2.7.9_Microsoft IronPython_.NET和Python实现平台下载 v2.7.9.1000最新官方版
- java 请求http get_java http get/post请求
- 【spring boot】【thymeleaf】SPEL处理 null 值