python基础小结

python中sys.argv函数精简概括

  • sys.argv[0]:给定脚本名是 ‘-‘ (标准输入)时,sys.argv[0] 是 ‘-‘。使用 -c command 时,sys.argv[0] 是 ‘-c’。如果使用选项 -m module,sys.argv[0] 就是包含目录的模块全名。
  • sys.argv[1]:sys.argv[1]是输出了参数所组成的列表的第一个元素
  • sys.argv[1:]:sys.argv[1:]是输出了参数所组成的列表,空格分割
1
2
3
4
import sys
print(sys.argv[0])
print(sys.argv[1])
print(sys.argv[1:])

python文件编码说明

python 支持3种编码声明,一般常用能见到下面两种

1
2
3
1.# -*- coding: utf-8 -*-

这种写法是为了兼容Emacs的编码声明
1
2
3
2.短一点,但Emacs不能用# coding=utf-8

短一点,但Emacs不能用

之所以要声明未编码类型 ,主要是中文出错的问题。

在python 文件开头(一般是第一行或第二行),用来说明你的Python源程序文件用使用的编码。缺省情况下你的程序需要使用ascii码来写,但如果在其中写中文的话,python解释器一般会报错,但如果加上你所用的文件编码,python就会自动处理不再报错。

这里要注意的是:

1.coding 后面使用 “:” 或 “=” 都可以

2.但是, “:” 或 “=” 必须和 coding之间没有空格。之前我就试过有空格声明失败,还是不支持中文。至于 “:” 或 “=” 后面,有没有空格就没所谓了。

Python -c 执行命令

1. 查看 Python 版本

1
2
3
4
5
6
7
strong@foreverstrong:~$ python -V
Python 3.6.8
strong@foreverstrong:~$

strong@foreverstrong:~$ python --version
Python 3.6.8
strong@foreverstrong:~$

2. 查看 Python 安装路径

1
2
3
4
5
6
7
8
9
10
11
12
strong@foreverstrong:~$ python -c "import sys; print(sys.executable)"
/usr/bin/python
strong@foreverstrong:~$


strong@foreverstrong:~$ python -c "import os; print(os.sys.executable)"
/usr/bin/python
strong@foreverstrong:~$

strong@foreverstrong:~$ python -c "import os; path = os.sys.executable; folder=path[0 : path.rfind(os.sep)]; print(folder)"
/usr/bin
strong@foreverstrong:~$

Python -m 执行命令

在 Python3 中,只需一行命令就能实现一个简单的 HTTP 服务:

1
2
3
4
python -m http.server 8000

# 注:在 Python2 中是这样
python -m SimpleHTTPServer 8000

执行后,在本机打开“ http://localhost:8000 ”,或者在局域网内的其它机器上打开“ http://本机ip:8000 ”,就能访问到执行目录下的内容。

与此类似,我们只需要一行命令“python -m pydoc -p xxx”,就能生成 HTML 格式的官方帮助文档,可以在浏览器中访问。

1
python -m pydoc -p 9000

上面的命令执行了 pydoc 模块,会在 9000 端口启动一个 http 服务.

它的第三个常见用法是执行 pdb 的调试命令“python -m pdb xxx.py”,以调试模式来执行“xxx.py”脚本:

1
python -m pdb test.py

第四个同样挺有用的场景是用 timeit 在命令行中测试一小段代码的运行时间。以下的 3 段代码,用不同的方式拼接 “0-1-2-……-99” 数字串。可以直观地看出它们的效率差异:

1
2
3
python -m timeit "'-'.join(str(n) for n in range(100))"
python -m timeit "'-'.join([str(n) for n in range(100)])"
python -m timeit "'-'.join(map(str,range(100)))"

最后,还有一种常常被人忽略的场景:“python -m pip install xxx”。我们可能会习惯性地使用“pip install xxx”,或者做了版本区分时用“pip3 install xxx”,总之不在前面用“python -m”做指定。但这种写法可能会出问题。

-m 选项的两种原理解析

看了前面的几种典型用法,你是否开始好奇: “-m”是怎么运作的?它是怎么实现的?

对于“python -m name”,一句话解释: Python 会检索 sys.path ,查找名字为“name”的模块或者包(含命名空间包),并将其内容当成“main”模块来执行。

1、对于普通模块

以“.py”为后缀的文件就是一个模块,在“-m”之后使用时,只需要使用模块名,不需要写出后缀,但前提是该模块名是有效的,且不能是用 C 语言写成的模块。

在“-m”之后,如果是一个无效的模块名,则会报错“No module named xxx”。

如果是一个带后缀的模块,则首先会导入该模块,然后可能报错:Error while finding module specification for ‘xxx.py’ (AttributeError: module ‘xxx’ has no attribute ‘path‘。

avatar

对于一个普通模块,有时候这两种写法表面看起来是等效的:
两种写法都会把定位到的模块脚本当成主程序入口来执行,即在执行时,该脚本的 name 都是”main“,跟 import 导入方式是不同的。

但它的前提是:在执行目录中存在着“test.py”,且只有唯一的“test”模块。对于本例,如果换一个目录执行的话,“python test.py”当然会报找不到文件的错误,然而,“python -m test”却不会报错,因为解释器在遍历 sys.path 时可以找到同名的“test”模块,并且执行:

avatar

由此差异,我们其实可以总结出“-m”的用法: 已知一个模块的名字,但不知道它的文件路径,那么使用“-m”就意味着交给解释器自行查找,若找到,则当成脚本执行。

直接运行脚本时,相当于给出了脚本的完整路径(不管是绝对路径还是相对路径),解释器根据 文件系统的查找机制, 定位到该脚本,然后执行 使用“-m”方式时,解释器需要在不 import 的情况下,在 所有模块命名空间 中查找,定位到脚本的路径,然后执行。为了实现这个过程,解释器会借助两个模块: pkgutil 和 runpy ,前者用来获取所有的模块列表,后者根据模块名来定位并执行脚本

2、对于包内模块

如果“-m”之后要执行的是一个包,那么解释器经过前面提到的查找过程,先定位到该包,然后会去执行它的“main”子模块,也就是说,在包目录下需要实现一个“main.py”文件。

换句话说,假设有个包的名称是“pname”,那么, “python -m pname”,其实就等效于“python -m pname.main”。