1. 快速打印函数的调用栈

在阅读源码的时候,有时候我们想要看整个程序的调用栈是怎样的?

比较常规的做法是使用全局搜索函数,一层一层往上走,效率非常之低。

而我习惯了使用 pdb 对代码进行调试,在使用pdb时,可以使用如下代码打出调用栈

import traceback
traceback.print_stack(file=sys.stdout)

或者直接使用 where (更简单的直接一个 w)把整个函数的调用栈给打印出来

(Pdb) where
  /usr/lib/python2.7/site-packages/eventlet/greenpool.py(82)_spawn_n_impl()
-> func(*args, **kwargs)
  /usr/lib/python2.7/site-packages/eventlet/wsgi.py(719)process_request()
-> proto.__init__(sock, address, self)
  /usr/lib64/python2.7/SocketServer.py(649)__init__()
-> self.handle()
  /usr/lib64/python2.7/BaseHTTPServer.py(340)handle()
-> self.handle_one_request()
  /usr/lib/python2.7/site-packages/eventlet/wsgi.py(384)handle_one_request()
-> self.handle_one_response()
  /usr/lib/python2.7/site-packages/eventlet/wsgi.py(481)handle_one_response()

2. 如何快速编译 Python 脚本?

pyc是一种二进制文件,是由py文件经过编译后,生成的文件,是一种byte code,py文件变成pyc文件后,加载的速度会有所提高。因此在一些场景下,可以预先编译成 pyc 文件,来提高加载速度。

编译的命令非常的简单,示例如下

$ tree demo
demo
└── main.py

$ python3 -O -m compileall demo
Listing 'demo'...
Compiling 'demo/main.py'...

$ tree demo
demo
├── __pycache__
│   └── main.cpython-39.opt-1.pyc
└── main.py

3. 交互模式下下划线的秒用

对于 _ ,大家对于他的印象都是用于 占位符,省得为一个不需要用到的变量,绞尽脑汁的想变量名。

今天要介绍的是他的第二种用法,就是在交互式模式下的应用。

示例如下:

>>> 3 + 4
7
>>> _
7
>>> name='iswbm'
>>> name
'iswbm'
>>> _
'iswbm'

它记录的是上一次表达式中返回的 非 None 值。

一定要是非 None值 ,否则 _ 存储的值不会被更新。这就是为什么print函数打印出来的值不会被存储。

>>> 3 + 4
7
>>> _
7
>>> print("iswbm")
iswbm
>>> _
7

因为 print 函数打印的内容并不是函数本身的返回值,print 函数返回的 None

4. 让脚本报错后立即进入调试模式

当你在使用 python xxx.py 这样的方法,执行 Python 脚本时,若因为代码 bug 导致异常未捕获,那整个程序便会终止退出。

这个时候,我们通常会去排查是什么原因导致的程序崩溃。

大家都知道,排查问题的思路,第一步肯定是去查看日志,若这个 bug 隐藏的比较深,只有在特定场景下才会现身,那么还需要开发者,复现这个 bug,方能优化代码。

复现有时候很难,有时候虽然简单,但是要伪造各种数据,相当麻烦。

如果有一种方法能在程序崩溃后,立马进入调试模式该有多好啊?

明哥都这么问了,那肯定是带着解决方案来的。

只要你在执行脚本行,加上 -i 参数,即可在脚本执行完毕后进入 Python Shell 模式,方便你进行调试。

具体演示如下:

python 打印栈异常 python打印调用栈_python


需要注意的是:脚本执行完毕,有两种情况:

  1. 正常退出
  2. 异常退出
    这两种都会进入 Python Shell,如果脚本并无异常,最终也会进入 Python Shell 模式,需要你手动退出

    如果希望脚本正确完成时自动推出,可以在脚本最后加上一行__import__(“os”)._exit(0)

5. 快速将项目打包成应用程序

假设我当前有一个 demo 项目,目录结构树及相关文件的的代码如下

python 打印栈异常 python打印调用栈_Python开发_02


现在我使用如下命令,将该项目进行打包,其中 demo 是项目的文件夹名,main:main 中的第一个 main 指的 main.py,而第二个 main 指的是 main 函数

$ python3 -m zipapp demo -m "main:main"

执行完成后,会生成一个 demo.pyz 文件,可直接执行它。

具体演示过程如下

python 打印栈异常 python打印调用栈_Python开发_03

6. 往 Python Shell 中传入参数

往一个 Python 脚本传入参数,是一件非常简单的事情。

比如这样:

$ python demo.py arg1 arg2

我在验证一些简单的 Python 代码时,喜欢使用 Python Shell 。

那有没有办法在使用 Python Shell 时,向上面传递参数一样,传入参数呢?

经过我的摸索,终于找到了方法,具体方法如下:

python 打印栈异常 python打印调用栈_Python_04

7. 最快查看包搜索路径的方式

当你使用 import 导入一个包或模块时,Python 会去一些目录下查找,而这些目录是有优先级顺序的,正常人会使用 sys.path 查看。

>>> import sys
>>> from pprint import pprint   
>>> pprint(sys.path)
['',
 '/usr/local/Python3.7/lib/python37.zip',
 '/usr/local/Python3.7/lib/python3.7',
 '/usr/local/Python3.7/lib/python3.7/lib-dynload',
 '/home/wangbm/.local/lib/python3.7/site-packages',
 '/usr/local/Python3.7/lib/python3.7/site-packages']
>>>

那有没有更快的方式呢?

我这有一种连 console 模式都不用进入的方法呢?

你可能会想到这种,但这本质上与上面并无区别

[wangbm@localhost ~]$ python -c "print('\n'.join(__import__('sys').path))"

/usr/lib/python2.7/site-packages/pip-18.1-py2.7.egg
/usr/lib/python2.7/site-packages/redis-3.0.1-py2.7.egg
/usr/lib64/python27.zip
/usr/lib64/python2.7
/usr/lib64/python2.7/plat-linux2
/usr/lib64/python2.7/lib-tk
/usr/lib64/python2.7/lib-old
/usr/lib64/python2.7/lib-dynload
/home/wangbm/.local/lib/python2.7/site-packages
/usr/lib64/python2.7/site-packages
/usr/lib64/python2.7/site-packages/gtk-2.0
/usr/lib/python2.7/site-packages

这里我要介绍的是比上面两种都方便的多的方法,一行命令即可解决

[wangbm@localhost ~]$ python3 -m site
sys.path = [
    '/home/wangbm',
    '/usr/local/Python3.7/lib/python37.zip',
    '/usr/local/Python3.7/lib/python3.7',
    '/usr/local/Python3.7/lib/python3.7/lib-dynload',
    '/home/wangbm/.local/lib/python3.7/site-packages',
    '/usr/local/Python3.7/lib/python3.7/site-packages',
]
USER_BASE: '/home/wangbm/.local' (exists)
USER_SITE: '/home/wangbm/.local/lib/python3.7/site-packages' (exists)
ENABLE_USER_SITE: True

从输出你可以发现,这个列的路径会比 sys.path 更全,它包含了用户环境的目录。

8. 使用自带的 telnet 端口检测工具

若你想检测指定的机器上有没有开放某端口,但本机并没有安装 telnet 工具,不如尝试一下 python 自带的 telnetlib 库,亦可实现你的需求。

检查 192.168.56.200 上的 22 端口有没有开放。

$ python3 -m telnetlib -d 192.168.56.200 22
Telnet(192.168.56.200,22): recv b'SSH-2.0-OpenSSH_7.4\r\n'
SSH-2.0-OpenSSH_7.4

Telnet(192.168.56.200,22): send b'\n'
Telnet(192.168.56.200,22): recv b'Protocol mismatch.\n'
Protocol mismatch.
Telnet(192.168.56.200,22): recv b''
*** Connection closed by remote host ***

9. 命令行式执行 Python 代码

有时候你只是想验证一小段 Python 代码是否可用时,通常有两种方法

  1. 输入 python 回车,进入 console 模式,然后敲入代码进行验证
  2. 将你的代码写入 demo.py 脚本中,然后使用 python demo.py 验证

其实还有一种更简单的方法,比如我要计算一个字符串的md5

$ python -c "import hashlib;print(hashlib.md5('hello').hexdigest())"
5d41402abc4b2a76b9719d911017c592

只要加 -c 参数,就可以输入你的 Python 代码了。

10. 用调试模式执行脚本

当你使用 pdb 进行脚本的调试时,你可能会先在目标代码处输入 import pdb;pdb.set_trace() 来设置断点。

除此之外,还有一种方法,就是使用 -m pdb

$ python -m pdb demo.py
> /Users/MING/demo.py(1)<module>()
-> import sys
(Pdb)

11. 如何快速搭建 HTTP 服务器

搭建FTP,或者是搭建网络文件系统,这些方法都能够实现Linux的目录共享。但是FTP和网络文件系统的功能都过于强大,因此它们都有一些不够方便的地方。比如你想快速共享Linux系统的某个目录给整个项目团队,还想在一分钟内做到,怎么办?很简单,使用Python中的SimpleHTTPServer。

SimpleHTTPServer是Python 2自带的一个模块,是Python的Web服务器。它在Python 3已经合并到http.server模块中。具体例子如下,如不指定端口,则默认是8000端口。

## python2
python -m SimpleHTTPServer 8888

## python3
python3 -m http.server 8888

python 打印栈异常 python打印调用栈_Python使用技巧_05


SimpleHTTPServer有一个特性,如果待共享的目录下有index.html,那么index.html文件会被视为默认主页;如果不存在index.html文件,那么就会显示整个目录列表。

12. 快速构建 HTML 帮助文档

当你不知道一个内置模块如何使用时,会怎么做呢?

百度?Google?

其实完全没必要,这里教你一个离线学习 Python 模块的方法。

是的,你没有听错。

就算没有外网网络也能学习 Python 模块.

你只要在命令行下输入 python -m pydoc -p xxx 命令即可开启一个 HTTP 服务,xxx 为端口,你可以自己指定。

$ python -m pydoc -p 5200
pydoc server ready at http://localhost:5200/

帮助文档的效果如下

python 打印栈异常 python打印调用栈_python_06

13. 最正确且优雅的装包方法

当你使用 pip 来安装第三方的模块时,通常会使用这样的命令

$ pip install requests

此时如果你的环境中有 Python2 也有 Python 3,那你使用这条命令安装的包是安装 Python2 呢?还是安装到 Python 3 呢?

就算你的环境上没有安装 Python2,那也有可能存在着多个版本的 Python 吧?比如安装了 Python3.8,也安装了 Python3.9,那你安装包时就会很困惑,我到底把包安装在了哪里?

但若你使用这样的命令去安装,就没有了这样的烦恼了

## 在 python2 中安装
$ python -m pip install requests

## 在 python3 中安装
$ python3 -m pip install requests

## 在 python3.8 中安装
$ python3.8 -m pip install requests

## 在 python3.9 中安装
$ python3.9 -m pip install requests

8. 使用 json.tool 来格式化 JSON

假设现在你需要查看你机器上的json文件,而这个文件没有经过任何的美化,阅读起来是非常困难的。

$ cat demo.json
{"_id":"5f12d319624e57e27d1291fe","index":0,"guid":"4e482708-c6aa-4ef9-a45e-d5ce2c72c68d","isActive":false,"balance":"$2,954.93","picture":"http://placehold.it/32x32","age":36,"eyeColor":"green","name":"MasseySaunders","gender":"male","company":"TALAE","email":"masseysaunders@talae.com","phone":"+1(853)508-3237","address":"246IndianaPlace,Glenbrook,Iowa,3896","about":"Velitmagnanostrudexcepteurduisextemporirurefugiataliquasunt.Excepteurvelitquiseuinexinoccaecatoccaecatveliteuet.Commodonisialiquipirureminimconsequatminimconsecteturipsumsitex.\r\n","registered":"2017-02-06T06:42:20-08:00","latitude":-10.269827,"longitude":-103.12419,"tags":["laborum","excepteur","veniam","reprehenderit","voluptate","laborum","in"],"friends":[{"id":0,"name":"DorotheaShields"},{"id":1,"name":"AnnaRosales"},{"id":2,"name":"GravesBryant"}],"greeting":"Hello,MasseySaunders!Youhave8unreadmessages.","favoriteFruit":"apple"}

这时候你就可以使用 python 的命令行来直接美化。

$ python -m json.tool demo.json
{
    "_id": "5f12d319624e57e27d1291fe",
    "about": "Velitmagnanostrudexcepteurduisextemporirurefugiataliquasunt.Excepteurvelitquiseuinexinoccaecatoccaecatveliteuet.Commodonisialiquipirureminimconsequatminimconsecteturipsumsitex.\r\n",
    "address": "246IndianaPlace,Glenbrook,Iowa,3896",
    "age": 36,
    "balance": "$2,954.93",
    "company": "TALAE",
    "email": "masseysaunders@talae.com",
    "eyeColor": "green",
    "favoriteFruit": "apple",
    "friends": [
        {
            "id": 0,
            "name": "DorotheaShields"
        },
        {
            "id": 1,
            "name": "AnnaRosales"
        },
        {
            "id": 2,
            "name": "GravesBryant"
        }
    ],
    "gender": "male",
    "greeting": "Hello,MasseySaunders!Youhave8unreadmessages.",
    "guid": "4e482708-c6aa-4ef9-a45e-d5ce2c72c68d",
    "index": 0,
    "isActive": false,
    "latitude": -10.269827,
    "longitude": -103.12419,
    "name": "MasseySaunders",
    "phone": "+1(853)508-3237",
    "picture": "http://placehold.it/32x32",
    "registered": "2017-02-06T06:42:20-08:00",
    "tags": [
        "laborum",
        "excepteur",
        "veniam",
        "reprehenderit",
        "voluptate",
        "laborum",
        "in"
    ]
}

15. 极简模式执行 Python Shell

在终端输入 Python 就会进入 Python Shell 。

方便是挺方便,就是有点说不出的难受,谁能告诉我,为什么要多出这么大一段无关的内容。

python 打印栈异常 python打印调用栈_python_07


这有点像,你上爱某艺看视频吧,都要先看个 90 秒的广告。如果你和我一样不喜欢这种 『牛皮癣』,那么可以加个 -q 参数,静默进入 Python Shell,就像下面这样子,开启了极简模式,舒服多了。

python 打印栈异常 python打印调用栈_python_08

16. 在执行任意代码前自动念一段平安经

最近的"平安经"可谓是引起了不小的风波啊。

作为一个正儿八经的程序员,最害怕的就是自己的代码上线出现各种各样的 BUG。

为此明哥就研究了一下,如何在你执行任意 Python 代码前,让 Python 解释器自动念上一段平安经,保佑代码不出 BUG 。

没想到还真被我研究出来了

做好心理准备了嘛?

我要开始作妖了,噢不,是开始念经了。

python 打印栈异常 python打印调用栈_Python使用技巧_09


感谢佛祖保佑,Everything is ok,No bugs in the code.

你一定很想知道这是如何的吧?

如果你对 Linux 比较熟悉,就会知道,当你在使用 SSH 远程登陆 Linux 服务器的时候?会读取 .bash_profile 文件加载一些环境变量。

.bash_profile 你可以视其为一个 shell 脚本,可以在这里写一些 shell 代码达到你的定制化需求。

而在 Python 中,也有类似 .bash_profile 的文件,这个文件一般情况下是不存在的。

我们需要新建一个用户环境目录,这个目录比较长,不需要你死记硬背,使用 site 模块的方法就可以获取,然后使用 mkdir -p 命令创建它。

python 打印栈异常 python打印调用栈_python 打印栈异常_10


在这个目录下,新建一个 usercustomize.py 文件,注意名字必须是这个,换成其他的可就识别不到啦。这个 usercustomize.py 的内容如下(明哥注:佛祖只保佑几个 Python 的主要应用方向,毕竟咱是 Python 攻城狮嘛…)

python 打印栈异常 python打印调用栈_Python使用技巧_11


这个文件我放在了我的 github 上,你可以点此前往获取。一切都完成后,无论你是使用 python xxx.py 执行脚本

python 打印栈异常 python打印调用栈_Python_12


还是使用 python 进入 Python Shell ,都会先念一下平安经保平安。

python 打印栈异常 python打印调用栈_Python_13

17. 启动 Python Shell 前自动执行某脚本

前一节我们介绍了一种,只要运行解释器就会自动触发执行 Python 脚本的方法。

除此之外,可还有其他方法呢?

当然是有,只不过相对来说,会麻烦一点了。

先来看一下效果,在 ~/Library/Python/3.9/lib/python/site-packages 目录下并没有 usercustomize.py 文件,但是在执行 python 进入 Python Shell 模式后,还是会打印平安经。

python 打印栈异常 python打印调用栈_Python使用技巧_14


这是如何做到的呢?

很简单,只要做两件事

第一件事,在任意你喜欢的目录下,新建 一个Python 脚本,名字也随意,比如我叫 startup.py,内容还是和上面一样

python 打印栈异常 python打印调用栈_Python使用技巧_15


第二件事,设置一个环境变量 PYTHONSTARTUP,指向你的脚本路径

$ export PYTHONSTARTUP=/Users/MING/startup.py

这样就可以了。

但是这种方法只适用于 Python Shell ,只不适合 Python 执行脚本的方法。

python 打印栈异常 python打印调用栈_Python使用技巧_16


如果要在脚本中实现这种效果,我目前想到最粗糙我笨拙的方法了 – 手动加载执行

python 打印栈异常 python打印调用栈_python 打印栈异常_17

18. 把模块当做脚本来执行 7 种方法及原理

1. 用法举例
前面的文章里其实分享过不少类似的用法。比如:

1、 快速搭建一个 HTTP 服务

## python2
$ python -m SimpleHTTPServer 8888

## python3
$ python3 -m http.server 8888

2、快速构建 HTML 帮助文档

$ python -m pydoc -p 5200

3、快速进入 pdb 调试模式

$ python -m pdb demo.py

4、最优雅且正确的包安装方法

$ python3 -m pip install requests

5、快速美化 JSON 字符串

$ echo '{"name": "MING"}' | python -m json.tool

6、快速打印包的搜索路径

$ python -m site

7、用于快速计算程序执行时长

$ python3 -m timeit '"-".join(map(str, range(100)))'

2. 原理剖析

上面的诸多命令,都有一个特点,在命令中都含有 -m 参数选项,而参数的值,SimpleHTTPServer, http.server, pydoc,pdb,pip, json.tool,site ,timeit这些都是模块或者包。

通常来说模块或者包,都是用做工具包由其他模块导入使用,而很少直接使用命令来执行(脚本除外)。

Python 给我们提供了一种方法,可以让我们将模块里的部分功能抽取出来,直接用于命令行式的调用。效果就是前面你所看到的。

那这是如何实现的呢?

最好的学习方式,莫过于模仿,直接以 pip 和 json 模块为学习对象,看看目录结构和代码都有什么特点。

先看一下 pip 的源码目录,发现在其下有一个 main.py 的文件,难道这是 -m 的入口?

python 打印栈异常 python打印调用栈_Python_18


再看一下 json.tool 的源码文件,json 库下面却没有 main.py 的文件。

这就很奇怪了。

不对,再回过头看,我们调用的不是 json 库,而是 json 库下的 tool 模块。

查看 tool 模块的源代码,有一个名为 main 的函数

python 打印栈异常 python打印调用栈_Python使用技巧_19


但它这不是关键,main 函数是在模块中直接被调用的。

只有当 namemain_ 时,main 函数才会被调用

if __name__ == '__main__':
    main()

当模块被导入时,name 的值为模块名,

而当模块被直接执行,name 的值就变成了 main

这下思路清晰了。

想要使用 -m 的方式执行模块,有两种方式:

  • 第一种:以 -m 的方式执行,只要在 package 下写一个 main.py 的文件即可。
  • 第二种:以 -m <package.module> 的方式执行,只要在 module 的代码中,定义一个 main
    函数,然后在最外层写入下面这段固定的代码
if __name__ == '__main__':
    main()

上面我将 -m 的使用情况分为两种,但是实际上,只有一种,对于第一种,你完全可以将 -m 理解为 -m <package.main> 的简写形式。

3. 实践一下

先把当前路径设置追加到 PATH 的环境变量中

$ export PATH=${PATH}:`pwd`

先来验证一下第一种方法。

然后在当前目录下新建一个demo 文件夹,并且在 demo 目录下新建一个 main.py 的文件,随便打印点东西

## __main__.py
print("hello, world")

然后直接执行如下命令,立马就能看到效果。

$ python3 -m demo
hello,world

执行过程如下:

python 打印栈异常 python打印调用栈_Python_20


再来验证一下使用第二种方法。

在 demo 目录下再新建一个 foobar.py 文件

## foobar.py
def main():
    print("hello, world")

if __name__ == "__main__":
    main()

最后执行一下如下命令,输出与预期相符

$ python3 -m demo.foobar
hello, foobar

4. -m 存在的意义

m 实现的效果,无异于直接执行一个 Python 模块/脚本。

那么问题就来了,那我直接执行不就行啦,何必多此一举再加个 -m 呢?

这个问题很有意思,值得一提。

当我们使用一个模块的时候,往往只需要记住模块名,然后使用 import 去导入它就行了。

之所以能这么便利,这得益于 Python 完善的导入机制,你完全不需要知道这个模块文件存在哪个目录下,它的绝对路径是什么?因为 Python 的包导入机制会帮你做这些事情。

换句话说,如果你不使用 -m 的方式,当你要使用 python -m json.tool,你就得这样子写

$ echo '{"name": "MING"}' | python /usr/lib64/python2.7/json/tool.py
{
    "name": "MING"
}

如此一对比,哪个更方便?你心里应该有数了。

19. 命令行式打开 idle 编辑脚本

在你安装 Python 解释器的时候,会有一个选项,让你选择是否安装 idle,这是一个极简的 Python 编辑器,对于有点 python 编码的经验的同学,一般都已经安装了更加专业的代码编辑器,比如 pycharm,vscode 等,所以一般是不会去勾选它的。

但是对于第一次接触 Python 编程的初学者来说,在自己的电脑上,大概率是没有安装代码编辑器的,这时候有一个现成的编辑器,可以尽快的将 hello world 跑起来,是一件非常重要的事情,因此初学者一般会被建议安装 idle,这也是为什么 idle 是大多数人的第一个 Python 代码编辑器。

在你安装了 idle 后,如果你使用 Windows 电脑,点击 py 文件会有使用 idle 打开的选项,非常方便你直接编辑 py 文件。

但如若你在 mac 电脑上,你的右键,是没有这个选项的,那如何使用 idle 打开编辑呢?

可以在终端上使用如下这条命令即可调用 idle 打开指定文件

python3 -m idlelib unshelve.py

使用的效果如下

python 打印栈异常 python打印调用栈_Python_21


如果你不加文件的路径,默认会打开 idle 的 shell 模式

python 打印栈异常 python打印调用栈_Python使用技巧_22

20. 快速计算字符串 base64编码

对字符串编码和解码
对一个字符串进行 base64 编码 和 解码(加上 -d 参数即可)

$ echo "hello, world" | python3 -m base64
aGVsbG8sIHdvcmxkCg==

$ echo "aGVsbG8sIHdvcmxkCg==" | python3 -m base64 -d
hello, world

效果如下

python 打印栈异常 python打印调用栈_python_23


对文件进行编码和解码

在命令后面直接加文件的路径

## 编码
$ python3 -m base64 demo.py
ZGVmIG1haW4oKToKICAgcHJpbnQoJ0hlbGxvIFdvcmxk8J+RjCcpCiAgIAppZiBfX25hbWVfXz09
J19fbWFpbl9fJzoKICAgbWFpbigpCg==

## 解码
$ echo "ZGVmIG1haW4oKToKICAgcHJpbnQoJ0hlbGxvIFdvcmxk8J+RjCcpCiAgIAppZiBfX25hbWVfXz09
J19fbWFpbl9fJzoKICAgbWFpbigpCg==" | python3 -m base64 -d
def main():
   print('Hello World ')

if __name__=='__main__':
   main()

效果如下

python 打印栈异常 python打印调用栈_Python使用技巧_24


如果你的文件是 py 脚本的话,可以直接执行它

python 打印栈异常 python打印调用栈_python_25

21. 快速找到指定文件的mime类型

识别 html 文件

## 可在线检测
$ python -m mimetypes https://docs.python.org/3/library/mimetypes.html
type: text/html encoding: None 

## 也可离线检测(后面不再赘述)
$ python -m mimetypes index.html
type: text/html encoding: None

识别图片格式

$ python -m mimetypes https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png
type: image/png encoding: None

识别 Python 脚本

$ python -m mimetypes sample.py
type: text/x-python encoding: None  # python文件

识别压缩文件

$ python -m mimetypes sample.py.gz
type: text/x-python encoding: gzip  # python文件,gzip压缩

22. 快速查看 Python 的环境信息

所有与 Python 相关的信息与配置,你都可以使用下面这条命令将其全部打印出来

$ python -m sysconfig

信息包括:

  • 你当前的操作系统平台
  • Python 的具体版本
  • 包的搜索路径
  • 以及各种环境变量

23.快速解压和压缩文件

tar 格式压缩包
创建一个 tar 压缩包

## 将 demo 文件夹压缩成 demo.tar 
$ python3 -m tarfile -c demo.tar demo

解压 tar 压缩包

## 解压 demo.tar 到 demo_new 文件夹下
$ python3 -m tarfile -e demo.tar demo_new

gzip 格式压缩包
创建一个 gzip 格式的压缩包(gzip 的输入,只能是一个文件,而不能是一个目录)

$ ls -l | grep message
-rw-r--r--@  1 MING  staff      97985  4 22 08:30 message

## 将 message.html 文件夹压缩成 message.gz
$  python3 -m gzip message

$ ls -l | grep message
-rw-r--r--@  1 MING  staff      97985  4 22 08:30 message
-rw-r--r--   1 MING  staff      24908  5  4 12:49 message.gz

解压一个 gzip 格式的压缩包

$ rm -rf message

$ ls -l | grep message
-rw-r--r--   1 MING  staff         87  5  4 12:51 message.gz

## 解压 message.gz
$ python3 -m gzip -d message.gz

$ ls -l | grep message
-rw-r--r--   1 MING  staff         62  5  4 12:52 message
-rw-r--r--   1 MING  staff         87  5  4 12:51 message.gz

zip 格式压缩包

创建一个 zip 格式的压缩包

$ ls -l | grep demo
drwxr-xr-x   3 MING  staff         96  5  4 12:44 demo

## 压缩  demo 文件夹为 demo.zip
$ python3 -m zipfile -c demo.zip demo

$ ls -l | grep demo
drwxr-xr-x   3 MING  staff         96  5  4 12:44 demo
-rw-r--r--   1 MING  staff      74890  5  4 12:55 demo.zip

解压一个 zip 格式的压缩包

$ rm -rf demo

$ ls -l | grep demo
-rw-r--r--   1 MING  staff      74890  5  4 12:55 demo.zip

$ python3 -m zipfile -e demo.zip demo

$ ls -l | grep demo
drwxr-xr-x   3 MING  staff         96  5  4 12:57 demo
-rw-r--r--   1 MING  staff      74890  5  4 12:55 demo.zip