字符串

  1. Python 交互模式下使用 “_” 来使用上一次的结果值.
  2. 字符串不可以被更改, 它是不可变的. 但是可以被重新赋值.

列表

  1. Python 中的列表类似于数组而不是链表, 列表中的每一个都有一个索引, 这使得查找单个元素很方便, 但是指定索引的插入操作时间复杂度更高.
  2. “ 的优先级高于 “-“, “-32” 将被解释成 “-(32)”, 你可以写成 “(-3)2”.
  3. 把列表当堆栈使用(后进先出), 使用 append() 添加, 使用 pop() 删除.
  4. 把列表当队列使用(先进先出), 使用 insert() 效率不高, 因为会移动整个列表. 要实现队列,使用 collections.deque,它为在首尾两端快速插入和删除而设计。例如:
  1. >>> from collections import deque
  2. >>> queue = deque(["Eric", "John", "Michael"])
  3. >>> queue.append("Terry") # Terry arrives
  4. >>> queue.append("Graham") # Graham arrives
  5. >>> queue.popleft() # The first to arrive now leaves
  6. 'Eric'
  7. >>> queue.popleft() # The second to arrive now leaves
  8. 'John'
  9. >>> queue # Remaining queue in order of arrival
  10. deque(['Michael', 'Terry', 'Graham'])

循环的技巧

  1. 在迭代过程中修改迭代序列不安全(只有在使用链表这样的可变序列时才会有这样的情况)。如果你想要修改你迭代的序列(例如,复制选择项),你可以迭代它的复本。使用切割标识就可以很方便的做到这一点:
  1. >>> for w in words[:]: # Loop over a slice copy of the entire list.
  2. ... if len(w) > 6:
  3. ... words.insert(0, w)
  4. ...
  5. >>> words
  6. ['defenestrate', 'cat', 'window', 'defenestrate']
  1. 在序列中循环时,索引位置和对应值可以使用 enumerate() 函数同时得到:
  1. >>> for i, v in enumerate(['tic', 'tac', 'toe']):
  2. ... print(i, v)
  3. ...
  4. 0 tic
  5. 1 tac
  6. 2 toe
  1. 当逆向循环一个序列时,先正向定位序列,然后调用 reversed() 函数:
  1. >>> for i in reversed(range(1, 10, 2)):
  2. ... print(i)
  3. ...
  4. 9
  5. 7
  6. 5
  7. 3
  8. 1

浅拷贝与深拷贝

浅拷贝只是对表层的拷贝, 表层内存地址不同, 里层不管是可变还是不可变类型都是引用, 里层内存地址相同.
深拷贝是对嵌套的拷贝, 表里层内存地址不同, 有趣的是如果里层是不可变类型(如元组, “[1,2,3,(4,5)]”), Python 解释器为了节省内存会引用, 反之如果里层不可变类型中又嵌套了可变类型(“[1,2,3,(4,5,[6,7])]”), 那么这个嵌套可变类型的不可变类型内存地址会不同(完全拷贝).

添加模块导入路径

  1. >>> import sys
  2. >>> sys.path.append('/ufs/guido/lib/python')

模块

当你使用以下方式运行 Python 模块时,模块中的代码便会被执行:
python fibo.py <arguments>
模块中的代码会被执行,就像导入它一样,不过此时 __name__ 被设置为 "__main__"。这相当于,如果你在模块后加入如下代码:

  1. if __name__ == "__main__":
  2. import sys
  3. fib(int(sys.argv[1]))

就可以让此文件像作为模块导入时一样作为脚本执行。此代码只有在模块作为 “main” 文件执行时才被调用:

  1. $ python fibo.py 50
  2. 1 1 2 3 5 8 13 21 34

如果模块被导入,不会执行这段代码:

  1. >>> import fibo
  2. >>>

部分高级技巧

  • 为了减少一个编译模块的大小,你可以在 Python 命令行中使用 -O 或者 -OO-O 参数删除了断言语句,-OO 参数删除了断言语句和 doc 字符串。
    因为某些程序依赖于这些变量的可用性,你应该只在确定无误的场合使用这一选项。“优化的” 模块有一个 .pyo 后缀而不是 .pyc 后缀。未来的版本可能会改变优化的效果。
  • 来自 .pyc 文件或 .pyo 文件中的程序不会比来自 .py 文件的运行更快;.pyc.pyo 文件只是在它们加载的时候更快一些。
  • compileall 模块可以为指定目录中的所有模块创建 .pyc 文件(或者使用 -O 参数创建 .pyo 文件)。
  • 在 PEP 3147 中有很多关这一部分内容的细节,并且包含了一个决策流程。
  • 变量 sys.path 是解释器模块搜索路径的字符串列表。它由环境变量 PYTHONPATH 初始化,如果没有设定 PYTHONPATH ,就由内置的默认值初始化。你可以用标准的字符串操作修改它:
  1. >>> import sys
  2. >>> sys.path.append('/ufs/guido/lib/python')

内置函数

内置函数 dir() 用于按模块名搜索模块定义,它返回一个字符串类型的存储列表:

  1. >>> import fibo, sys
  2. >>> dir(fibo)
  3. ['__name__', 'fib', 'fib2']
  4. >>> dir(sys)

dir() 不会列出内置函数和变量名。如果你想列出这些内容,它们在标准模块 builtins 中定义:

  1. >>> import builtins
  2. >>> dir(builtins)

str.zfill() 它用于向数值的字符串表达左侧填充 0。该函数可以正确理解正负号:

  1. >>> '12'.zfill(5)
  2. '00012'

format
字段名后允许可选的 ':' 和格式指令。这允许对值的格式化加以更深入的控制。下例将 Pi 转为三位精度。

  1. >>> import math
  2. >>> print('The value of PI is approximately {0:.3f}.'.format(math.pi))
  3. The value of PI is approximately 3.142.

在字段后的 ':' 后面加一个整数会限定该字段的最小宽度,这在美化表格时很有用:

  1. >>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 7678}
  2. >>> for name, phone in table.items():
  3. ... print('{0:10} ==> {1:10d}'.format(name, phone))
  4. ...
  5. Jack ==> 4098
  6. Dcab ==> 7678
  7. Sjoerd ==> 4127

异常处理

最后一个 except 子句可以省略异常名称,以作为通配符使用。你需要慎用此法,因为它会轻易隐藏一个实际的程序错误!可以使用这种方法打印一条错误信息,然后重新抛出异常(允许调用者处理这个异常):

  1. import sys
  2. try:
  3. f = open('myfile.txt')
  4. s = f.readline()
  5. i = int(s.strip())
  6. except OSError as err:
  7. print("OS error: {0}".format(err))
  8. except ValueError:
  9. print("Could not convert data to an integer.")
  10. except:
  11. print("Unexpected error:", sys.exc_info()[0])
  12. raise

抛出异常

raise 语句允许程序员强制抛出一个指定的异常。例如:

  1. >>> raise NameError('HiThere')
  2. Traceback (most recent call last):
  3. File "<stdin>", line 1, in ?
  4. NameError: HiThere

如果你需要明确一个异常是否抛出,但不想处理它,raise 语句可以让你很简单的重新抛出该异常:

  1. >>> try:
  2. ... raise NameError('HiThere')
  3. ... except NameError:
  4. ... print('An exception flew by!')
  5. ... raise
  6. ...
  7. An exception flew by!
  8. Traceback (most recent call last):
  9. File "<stdin>", line 2, in ?
  10. NameError: HiThere

用户自定义异常

在程序中可以通过创建新的异常类型来命名自己的异常(Python 类的内容请参见 )。异常类通常应该直接或间接的从 Exception 类派生,例如:

  1. >>> class MyError(Exception):
  2. ... def __init__(self, value):
  3. ... self.value = value
  4. ... def __str__(self):
  5. ... return repr(self.value)
  6. ...
  7. >>> try:
  8. ... raise MyError(2*2)
  9. ... except MyError as e:
  10. ... print('My exception occurred, value:', e.value)
  11. ...
  12. My exception occurred, value: 4
  13. >>> raise MyError('oops!')
  14. Traceback (most recent call last):
  15. File "<stdin>", line 1, in ?
  16. __main__.MyError: 'oops!'

日志

logging 模块提供功能齐全且灵活的日志记录系统。在最简单的情况下,日志消息被发送到文件或 sys.stderr

  1. import logging
  2. logging.debug('Debugging information')
  3. logging.info('Informational message')
  4. logging.warning('Warning:config file %s not found', 'server.conf')
  5. logging.error('Error occurred')
  6. logging.critical('Critical error -- shutting down')

这会产生以下输出:

  1. WARNING:root:Warning:config file server.conf not found
  2. ERROR:root:Error occurred
  3. CRITICAL:root:Critical error -- shutting down

默认情况下,informational 和 debugging 消息被压制,输出会发送到标准错误流。其他输出选项包括将消息转发到电子邮件,数据报,套接字或 HTTP 服务器。新的过滤器可以根据消息优先级选择不同的路由方式:DEBUGINFOWARNINGERROR,和 CRITICAL

日志系统可以直接从 Python 配置,也可以从用户配置文件加载,以便自定义日志记录而无需更改应用程序。

十进制浮点运算

  1. >>> from decimal import *
  2. >>> round(Decimal('0.70') * Decimal('1.05'), 2)
  3. Decimal('0.74')
  4. >>> round(.70 * 1.05, 2)
  5. 0.73

快捷创建虚拟环境

用于创建和管理虚拟环境的模块称为 venvvenv 通常会安装你可用的最新版本的 Python。如果您的系统上有多个版本的 Python,您可以通过运行 python3 或您想要的任何版本来选择特定的Python版本。
要创建虚拟环境,请确定要放置它的目录,并将 venv 模块作为脚本运行目录路径:

  1. python3 -m venv tutorial-env

如果它不存在,这将创建 tutorial-env 目录,并在其中创建包含Python解释器,标准库和各种支持文件的副本的目录。
创建虚拟环境后,您可以激活它。
在Windows上,运行:

  1. tutorial-env\Scripts\activate.bat

在Unix或MacOS上,运行:

  1. source tutorial-env/bin/activate

(这个脚本是为bash shell编写的。如果你使用 cshfish shell,你应该改用 activate.cshactivate.fish 脚本。)

浮点算术

  1. 对于需要精确十进制表示的使用场景,请尝试使用 decimal 模块,该模块实现了适合会计应用和高精度应用的十进制运算。
  2. Python 也提供了一些工具,可以在你真的 想要 知道一个浮点数精确值的少数情况下提供帮助。 例如 float.as_integer_ratio() 方法会将浮点数表示为一个分数:
  1. >>> x = 3.14159
  2. >>> x.as_integer_ratio()
  3. (3537115888337719, 1125899906842624)

由于这是一个精确的比值,它可以被用来无损地重建原始值:

  1. >>> x == 3537115888337719 / 1125899906842624
  2. True
  1. float.hex() 方法会以十六进制(以 16 为基数)来表示浮点数,同样能给出保存在你的计算机中的精确值:
  1. >>> x.hex()
  2. '0x1.921f9f01b866ep+1'

这种精确的十六进制表示法可被用来精确地重建浮点值:

  1. >>> x == float.fromhex('0x1.921f9f01b866ep+1')
  2. True

由于这种表示法是精确的,它适用于跨越不同版本(平台无关)的 Python 移植数值,以及与支持相同格式的其他语言(例如 Java 和 C99)交换数据.

其他

** 文件对象还有一些不太常用的附加方法,比如 isatty()truncate() 在库参考手册中有文件对象的完整指南。