上周编写了一个 Python 脚本用于将一堆包含 oracle dmp 文件的 rar 压缩包恢复到 oracle 数据库。由于 oracle dmp 文件恢复速度较慢,通过 nohup commad 2>&1 & 提交命令到后台运行。运行过程中发现通过 print 命令输出内容无法及时地重定向到 nohup.out 文件,nohup.out 文件里面会先显示调用 bash 命令的输出内容,然后再显示 print 语句的输出内容,而不会按顺序显示响应的内容。这里,编写一个简单的脚本模拟一下。

# demo.py#!/bin/env/python3
import subprocessprint('First line 1')
subprocess.run("echo Second line 2", shell=True, check=True)
print('Third line 3')

直接执行命令python3 demo.py ,得到的输出结果如下:

$ python3 demo.py
First line 1
Second line 2
Third line 3

通过命令 python3 demo.py > 1.out 重定向到 1.out 文件的结果如下:

$ python3 demo.py > 1.out
$ cat 1.out
Second line 2
First line 1
Third line 3

可以看到重定向后的输出内容的顺序和没有重定向的输出顺序不一样,使用 echo 命令的内容被重定向到文件 demo.out 以后,两条 print 语句的内容才顺序显示出来。后面去请教了一个同事,经过这个同事的指导才知道是因为再重定向的时候如果不指定 -u 选项,那么 Python 会默认将标准输出和标准错误进行缓存,等缓存区满了以后,再整体输出:

$ python3 -u demo.py > 2.out
$ cat 2.out
First line 1
Second line 2
Third line 3

问题解决以后,才理解了最近在编写使用 Python 项目的 Dockerfile 时,参照官方教程加上指令: ENV PYTHONUNBUFFERED 1 的含义。后来好好看了一下 python --help 的输出信息,才突然发现原来 Cpython 解释器支持这么多的命令行选项,因此写了这篇文章将这些容易被忽略的命令行参数好好说明一下。

- m <module-name>

以脚本的形式运行相应的模块,也就是执行相应Python 包在 __main__ 脚本里的内容,如果该块能够以脚本的方式运行的话。最常用的是虚拟环境管理模块 venv 和 Python 代码运行时间计算模块 timeit ,举例如下:

# 第一个 venv 是模块名字,第二个 venv 是创建的虚拟环境的名字
$ python -m venv venv
$ ls -lh venv/
total 4.0K
drwxrwxr-x. 2 yq yq 173 Aug 20 21:38 bin
drwxrwxr-x. 2 yq yq   6 Aug 20 21:38 include
drwxrwxr-x. 3 yq yq  23 Aug 20 21:38 lib
lrwxrwxrwx. 1 yq yq   3 Aug 20 21:38 lib64 -> lib
-rw-rw-r--. 1 yq yq  75 Aug 20 21:38 pyvenv.cfg
# 激活虚拟环境
$ source venv/bin/activate
# 推出虚拟环境
(venv) $ deactivate# 利用模块 timeit 计算 Python 代码时间
$ python3 -m timeit '"-".join(str(n) for n in range(100))'
10000 loops, best of 3: 49.2 usec per loop
$ python3 -m timeit '"-".join([str(n) for n in range(100)])'
10000 loops, best of 3: 42.2 usec per loop
$ python3 -m timeit '"-".join(map(str, range(100)))'
10000 loops, best of 3: 32.7 usec per loop

- u

强制标准输出流和标准错误流不进行缓存,直接输出。如上所述,当我们需要重定向 Python 脚本的输出到一个文件的时候,在执行脚本的时候加上 -u 参数,能够让内容及时输出到对应的文件,而不会出现顺序混乱的结果。而当我们使用交互的 Python解释器的时候,stdout 输出流默认是行缓存的 (line-buffered),因而我们直接使用 print 语句进行输出的时候,内容会及时显示,因为 print 函数包含了默认参数 end='n' ,举例如下:

# 下面是 Python print 函数的接口
print(*objects, sep=' ', end='n', file=sys.stdout, flush=False)# print 函数默认在输入内容后面加上 'n',因而只要接收到一个数字,便会输出
>>> for i in range(3):
...     print(i)
...
0
1
2# print 函数的参数 end 改成了空字符串,因而输出内容会默认缓冲
# 输出内容 012 缓存后一起输出
>>> for i in range(3):
...     print(i, end = '')
...     time.sleep(0.2)
...
012# 和上面相比,这里设置 flush 为 True
# 因此最终的显示效果会是接收到输出内容 1 的时候,就会立即输出
# 下面这段代码会依次显示0 1 2,而不是一次性输出012
for i in range(3):
...     print(i, end = '', flush=True)
...     time.sleep(0.2)
...
012

- b

当代码里面包括以下类型的比较的时候,Python 解释器会给出警告提示:1. 字符串类型(str)和 字节类型(bytes);2. 字符串类型(str)和字节数组类型(bytearrary);3. 字符串类型(str)和 整数类型(int)。举例如下:

$cat compare.py
str1 = '23'
bytes1 = b'23'
bytearray1 = bytearray(b'23')
int1 = 23if str1 == bytes1:print('Equal!')if str1 == bytearray1:print('Equal!')if bytes1 == int1:print('Equal!')$ python -b compare.py
compare.py:6: BytesWarning: Comparison between bytes and stringif str1 == bytes1:
compare.py:9: BytesWarning: Comparison between bytearray and stringif str1 == bytearray1:
compare.py:12: BytesWarning: Comparison between bytes and intif bytes1 == int1:# 使用 -bb 的时候,会抛出错误而不是警告
$ python -bb compare.py
Traceback (most recent call last):File "compare.py", line 6, in <module>if str1 == bytes1:
BytesWarning: Comparison between bytes and string

关于更多的 Python 命令行参数,可以参照 Python 的官方文档,也可以通过 python --help 查看。这里不在详细介绍每一个参数,剩下的参数大致包括以下内容:

-B: 是否生成相应的 `pyc` 文件
-c cmd:执行字符串命令 `cmd`
-d:启用调试
-E:忽略所有的 `PYTHON*` 环境变量
-I:忽略用户自己的环境信息,包括
-O:生成的 `pyc` 文件不包含 `assert` 语句和 `__debug__` 信息
-OO:在 `-O` 的基础上,进一步忽略代码的一些注释字符串
-q:交互式模式下不显示 Python 的版本和版权信息
-s:排除用户自己安装的 Python 模块
-S:在启动 Python 的时候不导入模块 `site`
-v:打印更多的代码执行的相关信息
-V:打印 Python 解释器的版本号
-W arg:警告的相关控制参数
-x:跳过代码里面的第一行(`#!cmd`)
-X:一些 Python 代码执行时的参数控制
--check-hash-based-pycs:设置是否对 `pyc` 文件进行 hash 校验

等有空了在好好看看 Python 官方文档里关于 Command line and environment 这一章节,将其中和 Python 相关的环境变量给大家在好好介绍一下。

参考链接

[1] https://docs.python.org/3/using/cmdline.html?highlight=pythonunbuffered

git 忽略__pycache___容易被忽略的 Python 命令行参数相关推荐

  1. Python 命令行参数:Argparse 与 Click

    Python 命令行参数:Argparse 与 Click 简介 一.Argparse 模块 1.1 概念 1.2 基础 1.3 位置参数介绍 1.4 可选参数介绍 1.5 短选项 1.6 结合位置参 ...

  2. 【Python】Python3.7.3 - Python命令行参数详解

    文章目录 Python命令行参数概览 -c cmd参数示例 -m mod参数示例 file参数示例 - 参数示例 命令行选项详解 -b 选项 -B选项 -d选项 -E选项 -h / -? / --he ...

  3. python命令行参数解析OptionParser类用法实例

    python命令行参数解析OptionParser类用法实例 本文实例讲述了python命令行参数解析OptionParser类的用法,分享给大家供大家参考. 具体代码如下:     from opt ...

  4. Python命令行参数解析模块getopt使用实例

    这篇文章主要介绍了Python命令行参数解析模块getopt使用实例,本文讲解了使用语法格式.短选项参数实例.长选项参数实例等内容,需要的朋友可以参考下 格式 getopt(args, options ...

  5. 对于python命令行参数使用,你应该这么做才专业

    python命令行参数 在python开发中,我们经常会遇到在执行代码时,需要给代码传参的情况. 遇到传参的场景,最基础的传参方式为*.py argv1 argv2 ...,然后我们在代码中通过sya ...

  6. python 代码命令大全-Python 命令行参数

    Python 命令行参数 Python 提供了 getopt 模块来获取命令行参数. $ python test.py arg1 arg2 arg3 Python 中也可以使用 sys 的 sys.a ...

  7. python 命令行 参数_Python命令行参数

    python 命令行 参数 Python Command line arguments are input parameters passed to the script when executing ...

  8. python命令行参数 空格_Python 命令行参数

    Python 命令行参数 Python 提供了 getopt 模块来获取命令行参数. $ python test.py arg1 arg2 arg3 Python 中也可以使用 sys 的 sys.a ...

  9. 一日一技python安装_一日一技:快速实现Python 命令行参数

    一日一技:快速实现Python 命令行参数 摄影:产品经理 厨师:kingname 我们有时候需要使用 Python 开发一些命令行工具,并在运行命令的时候指定一些参数,例如: python3 xxx ...

最新文章

  1. Nature Communications∣开花过程中,拟南芥茎尖分生组织基因表达和组蛋白标记的时空动态
  2. Windows Server 2008中部署AD
  3. 艾伟也谈项目管理,谈谈如何说“不”
  4. Sybase identity 字段
  5. 解决:Field xxMapper in xx.service.impl.xxServiceImpl required a bean of type ‘xx.mapper.xxMapper‘
  6. 商用计算机低温工作,突破量子计算机瓶颈!超低温芯片能在接近绝对零度的温度下工作...
  7. threejs 局部辉光
  8. SQL Server 2012安装配置(Part2 )
  9. 冰点密码忘记了怎么办
  10. springboot mongo查询固定字段_SpringBoot中文参考指南(2.1.6)32、使用 NoSQL 技术
  11. js 微信端 信息一键导入 通讯录
  12. 求两个数的最小公倍数及多个数的最小公倍数的求法
  13. python shutil删除_Python标准库shutil中用于删除文件夹的方法是( )
  14. Hi,欢迎大家来到阿毛小猪的博客,分享自己学习中的经验,默默的前行,聆听心的声音...
  15. 前端开发工具WebStorm下载
  16. 趣图:Python 程序员转 Java
  17. IE10访问Apache2.4卡死的问题
  18. 推荐一个免费超级好用的简历模板网站
  19. Pytorch:RNN、LSTM、GRU 构建人名分类器(one-hot版本、Embedding嵌入层版本)
  20. Java核心技术卷一 -第九章:集合

热门文章

  1. LeetCode 21. 合并两个有序链表(单链表)
  2. python3 可执行文件_将python3打包成为exe可执行文件(pyinstaller)
  3. Flask入门之上传文件到本地服务器
  4. python中进程创建—fork()
  5. 签到 数据库php,php与数据库的连接用法 (签到一)
  6. a算法TSP旅行商java_A*算法实现旅行商问题(人工智能报告,付代码)
  7. 中文python笔记_Python学习笔记-基础篇
  8. 论文浅尝 | Data Intelligence第4期正式上线啦
  9. 参会邀请 - CCKS2020 | 2020全国知识图谱与语义计算大会(CCKS2020)明日开幕
  10. 机器学习算法中的准确率、精确率、召回率和F值