字符串
- 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 arrivaldeque(['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 tic1 tac2 toe
- 当逆向循环一个序列时,先正向定位序列,然后调用
reversed()函数:
>>> for i in reversed(range(1, 10, 2)):... print(i)...97531
浅拷贝与深拷贝
浅拷贝只是对表层的拷贝, 表层内存地址不同, 里层不管是可变还是不可变类型都是引用, 里层内存地址相同.
深拷贝是对嵌套的拷贝, 表里层内存地址不同, 有趣的是如果里层是不可变类型(如元组, “[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 sysfib(int(sys.argv[1]))
就可以让此文件像作为模块导入时一样作为脚本执行。此代码只有在模块作为 “main” 文件执行时才被调用:
$ python fibo.py 501 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 ==> 4098Dcab ==> 7678Sjoerd ==> 4127
异常处理
最后一个 except 子句可以省略异常名称,以作为通配符使用。你需要慎用此法,因为它会轻易隐藏一个实际的程序错误!可以使用这种方法打印一条错误信息,然后重新抛出异常(允许调用者处理这个异常):
import systry: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 logginglogging.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 foundERROR:root:Error occurredCRITICAL: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 / 1125899906842624True
float.hex()方法会以十六进制(以 16 为基数)来表示浮点数,同样能给出保存在你的计算机中的精确值:
>>> x.hex()'0x1.921f9f01b866ep+1'
这种精确的十六进制表示法可被用来精确地重建浮点值:
>>> x == float.fromhex('0x1.921f9f01b866ep+1')True
由于这种表示法是精确的,它适用于跨越不同版本(平台无关)的 Python 移植数值,以及与支持相同格式的其他语言(例如 Java 和 C99)交换数据.
其他
** 文件对象还有一些不太常用的附加方法,比如 isatty() 和 truncate() 在库参考手册中有文件对象的完整指南。
