字符串
- Python 交互模式下使用 “_” 来使用上一次的结果值.
- 字符串不可以被更改, 它是不可变的. 但是可以被重新赋值.
列表
- Python 中的列表类似于数组而不是链表, 列表中的每一个都有一个索引, 这使得查找单个元素很方便, 但是指定索引的插入操作时间复杂度更高.
- ““ 的优先级高于 “-“, “-32” 将被解释成 “-(32)”, 你可以写成 “(-3)2”.
- 把列表当堆栈使用(后进先出), 使用 append() 添加, 使用 pop() 删除.
- 把列表当队列使用(先进先出), 使用 insert() 效率不高, 因为会移动整个列表. 要实现队列,使用 collections.deque,它为在首尾两端快速插入和删除而设计。例如:
>>> from collections import deque
>>> queue = deque(["Eric", "John", "Michael"])
>>> queue.append("Terry") # Terry arrives
>>> queue.append("Graham") # Graham arrives
>>> queue.popleft() # The first to arrive now leaves
'Eric'
>>> queue.popleft() # The second to arrive now leaves
'John'
>>> queue # Remaining queue in order of arrival
deque(['Michael', 'Terry', 'Graham'])
循环的技巧
- 在迭代过程中修改迭代序列不安全(只有在使用链表这样的可变序列时才会有这样的情况)。如果你想要修改你迭代的序列(例如,复制选择项),你可以迭代它的复本。使用切割标识就可以很方便的做到这一点:
>>> for w in words[:]: # Loop over a slice copy of the entire list.
... if len(w) > 6:
... words.insert(0, w)
...
>>> words
['defenestrate', 'cat', 'window', 'defenestrate']
- 在序列中循环时,索引位置和对应值可以使用 enumerate() 函数同时得到:
>>> for i, v in enumerate(['tic', 'tac', 'toe']):
... print(i, v)
...
0 tic
1 tac
2 toe
- 当逆向循环一个序列时,先正向定位序列,然后调用
reversed()
函数:
>>> for i in reversed(range(1, 10, 2)):
... print(i)
...
9
7
5
3
1
浅拷贝与深拷贝
浅拷贝只是对表层的拷贝, 表层内存地址不同, 里层不管是可变还是不可变类型都是引用, 里层内存地址相同.
深拷贝是对嵌套的拷贝, 表里层内存地址不同, 有趣的是如果里层是不可变类型(如元组, “[1,2,3,(4,5)]”), Python 解释器为了节省内存会引用, 反之如果里层不可变类型中又嵌套了可变类型(“[1,2,3,(4,5,[6,7])]”), 那么这个嵌套可变类型的不可变类型内存地址会不同(完全拷贝).
添加模块导入路径
>>> import sys
>>> sys.path.append('/ufs/guido/lib/python')
模块
当你使用以下方式运行 Python 模块时,模块中的代码便会被执行:
python fibo.py <arguments>
模块中的代码会被执行,就像导入它一样,不过此时 __name__
被设置为 "__main__"
。这相当于,如果你在模块后加入如下代码:
if __name__ == "__main__":
import sys
fib(int(sys.argv[1]))
就可以让此文件像作为模块导入时一样作为脚本执行。此代码只有在模块作为 “main” 文件执行时才被调用:
$ python fibo.py 50
1 1 2 3 5 8 13 21 34
如果模块被导入,不会执行这段代码:
>>> import fibo
>>>
部分高级技巧
- 为了减少一个编译模块的大小,你可以在 Python 命令行中使用 -O 或者 -OO。-O 参数删除了断言语句,-OO 参数删除了断言语句和 doc 字符串。
因为某些程序依赖于这些变量的可用性,你应该只在确定无误的场合使用这一选项。“优化的” 模块有一个 .pyo 后缀而不是 .pyc 后缀。未来的版本可能会改变优化的效果。 - 来自
.pyc
文件或.pyo
文件中的程序不会比来自.py
文件的运行更快;.pyc
或.pyo
文件只是在它们加载的时候更快一些。 - compileall 模块可以为指定目录中的所有模块创建
.pyc
文件(或者使用 -O 参数创建.pyo
文件)。 - 在 PEP 3147 中有很多关这一部分内容的细节,并且包含了一个决策流程。
- 变量
sys.path
是解释器模块搜索路径的字符串列表。它由环境变量 PYTHONPATH 初始化,如果没有设定 PYTHONPATH ,就由内置的默认值初始化。你可以用标准的字符串操作修改它:
>>> import sys
>>> sys.path.append('/ufs/guido/lib/python')
内置函数
内置函数 dir() 用于按模块名搜索模块定义,它返回一个字符串类型的存储列表:
>>> import fibo, sys
>>> dir(fibo)
['__name__', 'fib', 'fib2']
>>> dir(sys)
dir() 不会列出内置函数和变量名。如果你想列出这些内容,它们在标准模块 builtins 中定义:
>>> import builtins
>>> dir(builtins)
str.zfill() 它用于向数值的字符串表达左侧填充 0。该函数可以正确理解正负号:
>>> '12'.zfill(5)
'00012'
format
字段名后允许可选的 ':'
和格式指令。这允许对值的格式化加以更深入的控制。下例将 Pi 转为三位精度。
>>> import math
>>> print('The value of PI is approximately {0:.3f}.'.format(math.pi))
The value of PI is approximately 3.142.
在字段后的 ':'
后面加一个整数会限定该字段的最小宽度,这在美化表格时很有用:
>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 7678}
>>> for name, phone in table.items():
... print('{0:10} ==> {1:10d}'.format(name, phone))
...
Jack ==> 4098
Dcab ==> 7678
Sjoerd ==> 4127
异常处理
最后一个 except 子句可以省略异常名称,以作为通配符使用。你需要慎用此法,因为它会轻易隐藏一个实际的程序错误!可以使用这种方法打印一条错误信息,然后重新抛出异常(允许调用者处理这个异常):
import sys
try:
f = open('myfile.txt')
s = f.readline()
i = int(s.strip())
except OSError as err:
print("OS error: {0}".format(err))
except ValueError:
print("Could not convert data to an integer.")
except:
print("Unexpected error:", sys.exc_info()[0])
raise
抛出异常
raise 语句允许程序员强制抛出一个指定的异常。例如:
>>> raise NameError('HiThere')
Traceback (most recent call last):
File "<stdin>", line 1, in ?
NameError: HiThere
如果你需要明确一个异常是否抛出,但不想处理它,raise 语句可以让你很简单的重新抛出该异常:
>>> try:
... raise NameError('HiThere')
... except NameError:
... print('An exception flew by!')
... raise
...
An exception flew by!
Traceback (most recent call last):
File "<stdin>", line 2, in ?
NameError: HiThere
用户自定义异常
在程序中可以通过创建新的异常类型来命名自己的异常(Python 类的内容请参见 类 )。异常类通常应该直接或间接的从 Exception 类派生,例如:
>>> class MyError(Exception):
... def __init__(self, value):
... self.value = value
... def __str__(self):
... return repr(self.value)
...
>>> try:
... raise MyError(2*2)
... except MyError as e:
... print('My exception occurred, value:', e.value)
...
My exception occurred, value: 4
>>> raise MyError('oops!')
Traceback (most recent call last):
File "<stdin>", line 1, in ?
__main__.MyError: 'oops!'
日志
logging
模块提供功能齐全且灵活的日志记录系统。在最简单的情况下,日志消息被发送到文件或 sys.stderr
import logging
logging.debug('Debugging information')
logging.info('Informational message')
logging.warning('Warning:config file %s not found', 'server.conf')
logging.error('Error occurred')
logging.critical('Critical error -- shutting down')
这会产生以下输出:
WARNING:root:Warning:config file server.conf not found
ERROR:root:Error occurred
CRITICAL:root:Critical error -- shutting down
默认情况下,informational 和 debugging 消息被压制,输出会发送到标准错误流。其他输出选项包括将消息转发到电子邮件,数据报,套接字或 HTTP 服务器。新的过滤器可以根据消息优先级选择不同的路由方式:DEBUG
,INFO
,WARNING
,ERROR
,和 CRITICAL
。
日志系统可以直接从 Python 配置,也可以从用户配置文件加载,以便自定义日志记录而无需更改应用程序。
十进制浮点运算
>>> from decimal import *
>>> round(Decimal('0.70') * Decimal('1.05'), 2)
Decimal('0.74')
>>> round(.70 * 1.05, 2)
0.73
快捷创建虚拟环境
用于创建和管理虚拟环境的模块称为 venv
。venv
通常会安装你可用的最新版本的 Python。如果您的系统上有多个版本的 Python,您可以通过运行 python3
或您想要的任何版本来选择特定的Python版本。
要创建虚拟环境,请确定要放置它的目录,并将 venv
模块作为脚本运行目录路径:
python3 -m venv tutorial-env
如果它不存在,这将创建 tutorial-env
目录,并在其中创建包含Python解释器,标准库和各种支持文件的副本的目录。
创建虚拟环境后,您可以激活它。
在Windows上,运行:
tutorial-env\Scripts\activate.bat
在Unix或MacOS上,运行:
source tutorial-env/bin/activate
(这个脚本是为bash shell编写的。如果你使用 csh 或 fish shell,你应该改用 activate.csh
或 activate.fish
脚本。)
浮点算术
- 对于需要精确十进制表示的使用场景,请尝试使用
decimal
模块,该模块实现了适合会计应用和高精度应用的十进制运算。 - Python 也提供了一些工具,可以在你真的 想要 知道一个浮点数精确值的少数情况下提供帮助。 例如
float.as_integer_ratio()
方法会将浮点数表示为一个分数:
>>> x = 3.14159
>>> x.as_integer_ratio()
(3537115888337719, 1125899906842624)
由于这是一个精确的比值,它可以被用来无损地重建原始值:
>>> x == 3537115888337719 / 1125899906842624
True
float.hex()
方法会以十六进制(以 16 为基数)来表示浮点数,同样能给出保存在你的计算机中的精确值:
>>> x.hex()
'0x1.921f9f01b866ep+1'
这种精确的十六进制表示法可被用来精确地重建浮点值:
>>> x == float.fromhex('0x1.921f9f01b866ep+1')
True
由于这种表示法是精确的,它适用于跨越不同版本(平台无关)的 Python 移植数值,以及与支持相同格式的其他语言(例如 Java 和 C99)交换数据.
其他
** 文件对象还有一些不太常用的附加方法,比如 isatty()
和 truncate()
在库参考手册中有文件对象的完整指南。