python3官方教程
2019-05-16 10:05:06 0 举报
AI智能生成
python3 官方教程
作者其他创作
大纲/内容
2.使用 Python 解释器
安装python后你就可以使用解释器了
如何启动解释器
在命令行中输入 python
命令启动方式 : python -c "你要执行的命令" [arg] ...
模块启动方式:python -m module [arg] ...
如何退出
Linux
ctrl + d
windows
ctrl+z
通用
quit()
回看历史命令
ctrl + p
传入参数
解释器会读取命令行参数,转化为字符串列表存入 sys 模块中
通过 sys.argv 读取
交互模式
>>> the_world_is_flat = True
>>> if the_world_is_flat:
... print("Be careful not to fall off!")
...
Be careful not to fall off!
>>> if the_world_is_flat:
... print("Be careful not to fall off!")
...
Be careful not to fall off!
解释器的运行环境
定义编码(第一行)
# -*- coding: encoding -*-
特殊(当有定义可执行脚本时,编码得定义到第二行)
#!/usr/bin/env python3
# -*- coding: cp1252 -*-
# -*- coding: cp1252 -*-
4.控制流
if语句
if ... elif ... elif ...
for 语句
对任意序列进行迭代(例如列表或字符串)
range() 函数
遍历一个数字序列
以序列的索引来迭代
>>> a = ['Mary', 'had', 'a', 'little', 'lamb']
>>> for i in range(len(a)):
... print(i, a[i])
>>> for i in range(len(a)):
... print(i, a[i])
为节省空间。会在你迭代它时基于所希望的序列返回连续的项,但它没有真正生成列表
break
终止循环
循环含有 else
for
循环完执行else
while
false的时候执行else
遇到break时不会执行else
continue
继续执行最近的外层循环的下一个轮次
pass 语句
当语法上需要一个语句,但程序需要什么动作也不做时,可以使用它
占位符
>>> def initlog(*args):
... pass # Remember to implement this!
... pass # Remember to implement this!
函数
定义
>>> def func(*args):
... pass
... pass
def 跟函数名称和形式参数列表
构成函数体的语句从下一行开始,并且必须缩进。
文档字符串
>>> def my_function():
... """Do nothing, but document it.
...
... No, really, it doesn't do anything.
... """
... pass
...
>>> print(my_function.__doc__)
Do nothing, but document it.
No, really, it doesn't do anything.
... """Do nothing, but document it.
...
... No, really, it doesn't do anything.
... """
... pass
...
>>> print(my_function.__doc__)
Do nothing, but document it.
No, really, it doesn't do anything.
函数体的第一个语句可以(可选的)是字符串文字
第一行应该是对象目的的简要概述:以大写字母开头,以句点结尾。
多行,则第二行应为空白,后面几行应该是一个或多个段落,描述对象的调用约定,它的副作用等。
变量
函数中的所有变量赋值都将值存储在本地符号表中
变量引用查找
本地符号表中查找->封闭函数的本地符号表->全局符号表->内置符号表
全局变量不能直接在函数中赋值(除非使用 global 命名)
调用
实参是通过 按值调用 传递的(其中 值 始终是对象 引用 而不是对象的值)
当一个函数调用另外一个函数时,将会为该调用创建一个新的本地符号表。
重命名
>>> fib
<function fib at 10042ed0>
>>> f = fib
>>> f(100)
0 1 1 2 3 5 8 13 21 34 55 89
<function fib at 10042ed0>
>>> f = fib
>>> f(100)
0 1 1 2 3 5 8 13 21 34 55 89
return 语句
从函数内部返回一个值
默认返回 None
函数定义的更多形式
参数默认值
def ask_ok(prompt, retries=4, reminder='Please try again!'):
默认值只会执行一次
def f(a, L=[]):
L.append(a)
return L
print(f(1))
print(f(2))
print(f(3))
[1]
[1, 2]
[1, 2, 3]
L.append(a)
return L
print(f(1))
print(f(2))
print(f(3))
[1]
[1, 2]
[1, 2, 3]
可以看到 L 默认值只被执行一次
关键字参数
def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):
一个必需的参数(voltage)
三个可选的参数(state, action,和 type)
注意
关键字参数必须跟随在位置参数的后面
顺序并不重要
不能对同一个参数多次赋值
**name
接受一个字典
*name
接受一个元组
**name 与 *name例子
def cheeseshop(kind, *arguments, **keywords):
调用
cheeseshop("Limburger", "It's very runny, sir.",
"It's really very, VERY runny, sir.",
shopkeeper="Michael Palin",
client="John Cleese",
sketch="Cheese Shop Sketch")
"It's really very, VERY runny, sir.",
shopkeeper="Michael Palin",
client="John Cleese",
sketch="Cheese Shop Sketch")
解包参数列表
>>> list(range(3, 6)) # normal call with separate arguments
[3, 4, 5]
>>> args = [3, 6]
>>> list(range(*args)) # call with arguments unpacked from a list
[3, 4, 5]
[3, 4, 5]
>>> args = [3, 6]
>>> list(range(*args)) # call with arguments unpacked from a list
[3, 4, 5]
>>> def parrot(voltage, state='a stiff', action='voom'):
... print("-- This parrot wouldn't", action, end=' ')
... print("if you put", voltage, "volts through it.", end=' ')
... print("E's", state, "!")
...
>>> d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"}
>>> parrot(**d)
-- This parrot wouldn't VOOM if you put four million volts through it. E's bleedin' demised !
... print("-- This parrot wouldn't", action, end=' ')
... print("if you put", voltage, "volts through it.", end=' ')
... print("E's", state, "!")
...
>>> d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"}
>>> parrot(**d)
-- This parrot wouldn't VOOM if you put four million volts through it. E's bleedin' demised !
Lambda 表达式
一个小的匿名函数
lambda parameters: expression
相当于
def <lambda>(parameters):
return expression
return expression
函数标注
>>> def f(ham: str, eggs: str = 'eggs') -> str:
... print("Annotations:", f.__annotations__)
... print("Arguments:", ham, eggs)
... return ham + ' and ' + eggs
...
>>> f('spam')
Annotations: {'ham': <class 'str'>, 'return': <class 'str'>, 'eggs': <class 'str'>}
Arguments: spam eggs
'spam and eggs'
... print("Annotations:", f.__annotations__)
... print("Arguments:", ham, eggs)
... return ham + ' and ' + eggs
...
>>> f('spam')
Annotations: {'ham': <class 'str'>, 'return': <class 'str'>, 'eggs': <class 'str'>}
Arguments: spam eggs
'spam and eggs'
形参名称后加上冒号,后面跟一个表达式
返回值标注的定义方式是加上一个组合符号 ->,后面跟一个表达式
小插曲:编码风格
使用4个空格缩进,不要使用制表符
换行,使一行不超过79个字符
使用空行分隔函数和类,以及函数内的较大的代码块
把注释放到单独的一行
使用文档字符串
在运算符前后和逗号后使用空格
类和函数命名的一致性:规范是使用 CamelCase 命名类,lower_case_with_underscores 命名函数和方法
不要使用花哨的编码: 默认的 UTF-8 或者纯 ASCII 在任何情况下都能有最好的表现
6.模块
是什么?
定义函数实现具体功能,在不同的地方都可以被导入使用
导入模块
import 模块名
特性
模块有自己的私有符号表
作用
用作模块中定义的所有函数的全局符号表
不必担心与被调用者的变量冲突
模块可以导入其它模块
被导入的模块名存放在调入模块的全局符号表中。
from fibo import fib, fib2
fib, fib2 直接被导入现模块的符号表里
from fibo import *
导入模块内定义的所有名称
少用这种方式
因为它在解释器中引入了一组未知的名称,而它们很可能会覆盖一些你已经定义过的东西
import fibo as fib
导入 fibo 模块并以 fib 命名
脚本执行模块
文件需要定义
if __name__ == "__main__":
执行命令
python xxxx.py
模块搜索路径
sys.path 变量给出的目录列表里寻找 <- 内置模块
包含输入脚本的目录
PYTHONPATH
取决于安装的默认设置
“编译过的”Python文件
__pycache__ 目录里缓存了每个模块的编译后版本
加快模块载入
标准模块
内置的操作的访问
例如 模块 sys
被内嵌到每一个Python解释器中
查找模块定义的名称
dir()
包
什么是包
就是有多个模块的集合
避免引用模块名相同
通过 包名.模块名 来区分
目录中必须包含 __init__.py 文件
防止通用名称的目录隐藏在模块搜索路径上出现的有效模块中
从包中导入模块
导入单个模块
import sound.effects.echo
from sound.effects import echo
直接导入所需的函数或变量
from sound.effects.echo import echofilter
从包中导入 *
在目录中的 __init__.py 定义 __all__
__all__ = ["echo", "surround", "reverse"]
将导入 sound 包的三个命名子模块。
还是尽量用这种方式导入
from Package import specific_submodule
子包参考
绝对导入
from sound.effects import echo
相对导入
from . import echo
from .. import formats
from ..filters import equalizer
from .. import formats
from ..filters import equalizer
多个目录中的包
__path__
初始化为一个列表
包含 包的文件 __init__.py 的目录的名称
8.错误和异常
语法错误
>>> while True print('Hello world')
File "<stdin>", line 1
while True print('Hello world')
^
SyntaxError: invalid syntax
File "<stdin>", line 1
while True print('Hello world')
^
SyntaxError: invalid syntax
异常
形式
内置异常
系统预先定义好的异常
ZeroDivisionError
NameError
TypeError
...
自定义异常
创建
需要继承于 Exception
以执行任何其他类可以执行的任何操作,但通常保持简单
只提供相关属性,这些属性允许处理程序为异常提取有关错误的信息
例子
class Error(Exception):
"""Base class for exceptions in this module."""
pass
class InputError(Error):
def __init__(self, expression, message):
self.expression = expression
self.message = message
class TransitionError(Error):
def __init__(self, previous, next, message):
self.previous = previous
self.next = next
self.message = message
"""Base class for exceptions in this module."""
pass
class InputError(Error):
def __init__(self, expression, message):
self.expression = expression
self.message = message
class TransitionError(Error):
def __init__(self, previous, next, message):
self.previous = previous
self.next = next
self.message = message
处理异常
try...except
原理
首先,执行 try 子句
若无异常,跳过 except 子句 并完成 try 语句的执行
若有异常,跳过该try中剩下的部分。然后,如果异常的类型 == except 关键字后面的异常,则执行 except 子句 ,然后继续执行 try 语句之后的代码。
若发生的异常 != except 子句中指定的异常,则将其传递到外部的 try 语句中;若没有找到处理程序,则它是一个 未处理异常,执行将停止并显示如上所示的消息
处理多个异常
... except (RuntimeError, TypeError, NameError):
... pass
... pass
异常类之间的关系
异常和 except 子句中的类 == 同一个类或者是它的基类(兼容)
class B(Exception):
pass
class C(B):
pass
class D(C):
pass
for cls in [B, C, D]:
try:
raise cls()
except D:
print("D")
except C:
print("C")
except B:
print("B")
pass
class C(B):
pass
class D(C):
pass
for cls in [B, C, D]:
try:
raise cls()
except D:
print("D")
except C:
print("C")
except B:
print("B")
依次打印 B, C, D
except 子句可以省略异常名
except OSError as err:
print("OS error: {0}".format(err))
print("OS error: {0}".format(err))
try ... except...else
try 子句不引发异常时必须执行
finally
会在离开 try 语句前被执行,无论是否发生了异常
预定义的清理操作
with open("myfile.txt") as f:
for line in f:
print(line, end="")
for line in f:
print(line, end="")
异常名称后面指定一个变量
变量和一个异常实例绑定,它的参数存储在 instance.args 中
>>> try:
... raise Exception('spam', 'eggs')
... except Exception as inst:
... print(type(inst)) # the exception instance
... print(inst.args) # arguments stored in .args
... print(inst) # __str__ allows args to be printed directly,
... # but may be overridden in exception subclasses
... x, y = inst.args # unpack args
... print('x =', x)
... print('y =', y)
...
<class 'Exception'>
('spam', 'eggs')
('spam', 'eggs')
x = spam
y = eggs
... raise Exception('spam', 'eggs')
... except Exception as inst:
... print(type(inst)) # the exception instance
... print(inst.args) # arguments stored in .args
... print(inst) # __str__ allows args to be printed directly,
... # but may be overridden in exception subclasses
... x, y = inst.args # unpack args
... print('x =', x)
... print('y =', y)
...
<class 'Exception'>
('spam', 'eggs')
('spam', 'eggs')
x = spam
y = eggs
异常抛出
raise ValueError
10.标准库简介
操作系统接口
os
https://docs.python.org/zh-cn/3/library/os.html#module-os
日常文件和目录管理任务
shutil
https://docs.python.org/zh-cn/3/library/shutil.html#module-shutil
文件通配符
glob
https://docs.python.org/zh-cn/3/library/glob.html#module-glob
命令行参数
sys 模块的 argv
https://docs.python.org/zh-cn/3/library/sys.html#module-sys
错误输出重定向和程序终止
sys 模块 stdin , stdout 和 stderr 的属性
正则匹配
re
https://docs.python.org/zh-cn/3/library/re.html#module-re
数学
math
https://docs.python.org/zh-cn/3/library/math.html#module-math
random
https://docs.python.org/zh-cn/3/library/random.html#module-random
statistics
https://docs.python.org/zh-cn/3/library/statistics.html#module-statistics
互联网访问
urllib
https://docs.python.org/zh-cn/3/library/urllib.request.html#module-urllib.request
smtplib
https://docs.python.org/zh-cn/3/library/smtplib.html#module-smtplib
日期和时间
datetime
https://docs.python.org/zh-cn/3/library/datetime.html#module-datetime
数据压缩
zlib
gzip
bz2
lzma
zipfile
tarfile
性能测量
timeit
https://docs.python.org/zh-cn/3/library/timeit.html#module-timeit
质量控制
doctest
unittest
Batteries Included
包含电池什么鬼,说个简单理解的就是:开箱即用
12.虚拟环境和包
概述
解决不同的python程序需要使用不同的版本环境
创建虚拟环境
python3 -m venv tutorial-env
1.创建 tutorial-env 目录
2.包含Python解释器,标准库和各种支持文件的副本
激活虚拟环境
win
tutorial-env\Scripts\activate.bat
类Unix
source tutorial-env/bin/activate
使用pip管理包
搜索
pip search
安装
pip install
安装特定版本
pip install requests==2.6.0
将软件包升级到最新版本
pip install --upgrade requests
删除
pip uninstall
显示有关特定包的信息
pip show requests
显示虚拟环境中安装的所有软件包
pip list
将生成一个类似的已安装包列表
pip freeze > requirements.txt
安装列出的所有必需的包
pip install -r requirements.txt
14.交互式编辑和编辑历史
使用 GNU Readline 实现
使得 Python 解释器支持编辑当前输入行和编辑历史记录
Tab 补全和编辑历史
解释器启动
补全变量和模块名的功能将 自动打开
按下 Tab 键的时候调用补全函数
'.' 之前的表达式,接着根据求值结果对象的属性给出补全建议
.python_history
保存编辑历史记录
默认交互式解释器的替代
IPython
bpython
16. 附录
交互模式
错误处理
当发生错误时
交互模式下
返回到主命令提示符
输入内容来自文件
打印错误堆栈之后,程序会以非零状态退出
取消输入并返回主提示符
Control-C 或 Delete
可执行的Python脚本
Python脚本可以直接执行
#!/usr/bin/env python3.5
提供可执行模式或权限
$ chmod +x myscript.py
交互式启动文件
环境变量设置
PYTHONSTARTUP
从当前目录中读取一个额外的启动文件
if os.path.isfile('.pythonrc.py'): exec(open('.pythonrc.py').read())
定制模块
sitecustomize
usercustomize
>>> import site
>>> site.getusersitepackages()
'/home/user/.local/lib/python3.5/site-packages'
>>> site.getusersitepackages()
'/home/user/.local/lib/python3.5/site-packages'
在该目录中创建一个名为 usercustomize.py 的文件,并将所需内容放入其中。它会影响Python的每次启动,除非它以 -s 选项启动,以禁用自动导入。
1.课前甜点
python为你解决
自动化操作
数据库应用
游戏
。。。
对比其他语言
更简单
多平台使用
更快完成
容易使用
更多的错误检查
能够应付更多的问题
特点
模块化
python内置了很多模块,可以拿来用
你也可以自己开发模块,当你需要时拿来用就好了
解释型语言
对于那些一次性的程序来说很有用处
书写紧凑易读
一个表达式中可以复杂表示
代码块按照缩进划分
不需要预先定义变量或参数
可扩展
可以链接其他应用,从而使用python进行操作
3.Python 的非正式介绍
注释
以 # 开头
注释用来解释代码,不被 Python 解释
正确使用注释例子
# this is the first comment
spam = 1 # and this is the second comment
spam = 1 # and this is the second comment
Python 作为计算器使用
数字
运算符
+(加)
-(减)
*(乘)
/(除)
//(整除)
%(取余)
**(乘方)
字符串
形式
单引号('……')
双引号("……")
跨行 : 三重引号:"""...""" 或 '''...'''
转义
使用 \ 来表达特殊字符
原始字符串
引号前添加 r
>>> print('C:\some\name') # here \n means newline!
C:\some
ame
>>> print(r'C:\some\name') # note the r before the quote
C:\some\name
C:\some
ame
>>> print(r'C:\some\name') # note the r before the quote
C:\some\name
连接
+
重复
*
>>> # 3 times 'un', followed by 'ium'
>>> 3 * 'un' + 'ium'
'unununium'
>>> 3 * 'un' + 'ium'
'unununium'
索引
字符串可被 索引 (下标访问)
>>> word = 'Python'
>>> word[0] # character in position 0
'P'
>>> word[0] # character in position 0
'P'
>>> word[-1] # last character
'n'
'n'
切片
>>> word[0:2] # characters from position 0 (included) to 2 (excluded)
'Py'
'Py'
+---+---+---+---+---+---+
| P | y | t | h | o | n |
+---+---+---+---+---+---+
0 1 2 3 4 5 6
-6 -5 -4 -3 -2 -1
| P | y | t | h | o | n |
+---+---+---+---+---+---+
0 1 2 3 4 5 6
-6 -5 -4 -3 -2 -1
不能被修改
>>> word[0] = 'J'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
长度
len()
列表
[...,...,...]
也支持索引和切片
(浅)拷贝
切片操作都返回一个新列表
支持拼接
>>> squares + [36, 49, 64, 81, 100]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
内容可变
>>> cubes = [1, 8, 27, 65, 125] # something's wrong here
>>> 4 ** 3 # the cube of 4 is 64, not 65!
64
>>> cubes[3] = 64 # replace the wrong value
>>> cubes
[1, 8, 27, 64, 125]
>>> 4 ** 3 # the cube of 4 is 64, not 65!
64
>>> cubes[3] = 64 # replace the wrong value
>>> cubes
[1, 8, 27, 64, 125]
添加新元素
append()
赋值
>>> letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>> letters
['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>> # replace some values
>>> letters[2:5] = ['C', 'D', 'E']
>>> letters
['a', 'b', 'C', 'D', 'E', 'f', 'g']
>>> letters
['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>> # replace some values
>>> letters[2:5] = ['C', 'D', 'E']
>>> letters
['a', 'b', 'C', 'D', 'E', 'f', 'g']
长度
len()
嵌套
>>> a = ['a', 'b', 'c']
>>> n = [1, 2, 3]
>>> x = [a, n]
>>> x
[['a', 'b', 'c'], [1, 2, 3]]
>>> n = [1, 2, 3]
>>> x = [a, n]
>>> x
[['a', 'b', 'c'], [1, 2, 3]]
编程的第一步
a, b = 0, 1
多重赋值: 变量 a 和 b 同时得到了新值 0 和 1
while a < 10:
... print(a)
... print(a)
while 循环
循环体 是 缩进的
print(a, end=',')
关键字参数 end 可以用来取消输出后面的换行
>>> a, b = 0, 1
>>> while a < 1000:
... print(a, end=',')
... a, b = b, a+b
...
0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,
>>> while a < 1000:
... print(a, end=',')
... a, b = b, a+b
...
0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,
5.数据结构
列表
常用方法
list.append(x)
列表的末尾添加一个元素
>>> fruits = ['orange', 'apple', 'pear', 'banana', 'kiwi', 'apple', 'banana']
>>> fruits.append('grape')
>>> fruits
['banana', 'apple', 'kiwi', 'banana', 'pear', 'apple', 'orange', 'grape']
>>> fruits.append('grape')
>>> fruits
['banana', 'apple', 'kiwi', 'banana', 'pear', 'apple', 'orange', 'grape']
list.extend(iterable)
添加可迭代对象中的所有元素
list.insert(i, x)
在给定的位置插入一个元素
list.remove(x)
移除列表中第一个值为 x 的元素
list.pop([i])
删除列表中给定位置的元素并返回它,默认删除最后一个元素
>>> fruits = ['orange', 'apple', 'pear', 'banana', 'kiwi', 'apple', 'banana']
>>> fruits.pop()
'pear'
>>> fruits.pop()
'pear'
list.clear()
删除列表中所有的元素。
list.index(x[, start[, end]])
返回列表中第一个值为 x 的元素的从零开始的索引。
>>> fruits = ['orange', 'apple', 'pear', 'banana', 'kiwi', 'apple', 'banana']
>>> fruits.index('banana')
3
>>> fruits.index('banana', 4) # Find next banana starting a position 4
6
>>> fruits.index('banana')
3
>>> fruits.index('banana', 4) # Find next banana starting a position 4
6
list.count(x)
返回元素 x 在列表中出现的次数
>>> fruits = ['orange', 'apple', 'pear', 'banana', 'kiwi', 'apple', 'banana']
>>> fruits.count('apple')
2
>>> fruits.count('apple')
2
list.sort(key=None, reverse=False)
对列表中的元素进行排序
>>> fruits = ['orange', 'apple', 'pear', 'banana', 'kiwi', 'apple', 'banana']
>>> fruits.sort()
>>> fruits
['apple', 'apple', 'banana', 'banana', 'grape', 'kiwi', 'orange', 'pear']
>>> fruits.sort()
>>> fruits
['apple', 'apple', 'banana', 'banana', 'grape', 'kiwi', 'orange', 'pear']
list.reverse()
反转列表中的元素。
>>> fruits = ['orange', 'apple', 'pear', 'banana', 'kiwi', 'apple', 'banana']
>>> fruits.reverse()
>>> fruits
['banana', 'apple', 'kiwi', 'banana', 'pear', 'apple', 'orange']
>>> fruits.reverse()
>>> fruits
['banana', 'apple', 'kiwi', 'banana', 'pear', 'apple', 'orange']
list.copy()
返回列表的一个浅拷贝
作为栈使用
“后进先出”
>>> stack = [3, 4, 5]
>>> stack.append(6)
>>> stack.append(7)
>>> stack
[3, 4, 5, 6, 7]
>>> stack.pop()
7
>>> stack
[3, 4, 5, 6]
>>> stack.pop()
6
>>> stack.pop()
5
>>> stack
[3, 4]
>>> stack.append(6)
>>> stack.append(7)
>>> stack
[3, 4, 5, 6, 7]
>>> stack.pop()
7
>>> stack
[3, 4, 5, 6]
>>> stack.pop()
6
>>> stack.pop()
5
>>> stack
[3, 4]
作为队列
“先进先出”
相当低效
可以使用 queue
>>> 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'])
>>> 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'])
列表推导式
使用某种操作得出结果,将结果创建出列表
>>> squares = []
>>> for x in range(10):
... squares.append(x**2)
...
>>> squares
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> for x in range(10):
... squares.append(x**2)
...
>>> squares
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
squares = list(map(lambda x: x**2, range(10)))
squares = [x**2 for x in range(10)]
结构
一对方括号包含
一个表达式
一个 for 子句
零个或多个 for 或 if 子句
[(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]
>>> combs = []
>>> for x in [1,2,3]:
... for y in [3,1,4]:
... if x != y:
... combs.append((x, y))
...
>>> combs
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]
>>> for x in [1,2,3]:
... for y in [3,1,4]:
... if x != y:
... combs.append((x, y))
...
>>> combs
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]
嵌套的列表推导式
[[row[i] for row in matrix] for i in range(4)]
不太建议使用,可读性差
zip() 函数将会很好地处理这种情况
del 语句
根据索引移除列表中的值
>>> a = [-1, 1, 66.25, 333, 333, 1234.5]
>>> del a[0]
>>> a
[1, 66.25, 333, 333, 1234.5]
>>> del a[2:4]
>>> a
[1, 66.25, 1234.5]
>>> del a[:]
>>> a
[]
>>> del a[0]
>>> a
[1, 66.25, 333, 333, 1234.5]
>>> del a[2:4]
>>> a
[1, 66.25, 1234.5]
>>> del a[:]
>>> a
[]
直接移除整个列表
del 列表名
元组和序列
序列
列表
字符串
元组
元组由几个被逗号隔开的值组成
元组是 immutable (不可变的)
不允许给元组中的元素赋值
可以包含不同种类的元素
元组打包
t = 12345, 54321, 'hello!'
序列解包
>>> t = 11, 22, 33
>>> x, y, z = t
>>> x
11
>>> x, y, z = t
>>> x
11
集合
由不重复元素组成的无序的集
基本用法
成员检测
消除重复元素
支持像 联合,交集,差集,对称差分等数学运算
创建方式
{}
set()
例子
>>> basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}
>>> print(basket) # show that duplicates have been removed
{'orange', 'banana', 'pear', 'apple'}
>>> 'orange' in basket # fast membership testing
True
>>> 'crabgrass' in basket
False
>>> # Demonstrate set operations on unique letters from two words
...
>>> a = set('abracadabra')
>>> b = set('alacazam')
>>> a # unique letters in a
{'a', 'r', 'b', 'c', 'd'}
>>> a - b # letters in a but not in b
{'r', 'd', 'b'}
>>> a | b # letters in a or b or both
{'a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'}
>>> a & b # letters in both a and b
{'a', 'c'}
>>> a ^ b # letters in a or b but not both
{'r', 'd', 'b', 'm', 'z', 'l'}
>>> print(basket) # show that duplicates have been removed
{'orange', 'banana', 'pear', 'apple'}
>>> 'orange' in basket # fast membership testing
True
>>> 'crabgrass' in basket
False
>>> # Demonstrate set operations on unique letters from two words
...
>>> a = set('abracadabra')
>>> b = set('alacazam')
>>> a # unique letters in a
{'a', 'r', 'b', 'c', 'd'}
>>> a - b # letters in a but not in b
{'r', 'd', 'b'}
>>> a | b # letters in a or b or both
{'a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'}
>>> a & b # letters in both a and b
{'a', 'c'}
>>> a ^ b # letters in a or b but not both
{'r', 'd', 'b', 'm', 'z', 'l'}
推导式
>>> a = {x for x in 'abracadabra' if x not in 'abc'}
>>> a
{'r', 'd'}
>>> a
{'r', 'd'}
字典
以 关键字 为索引的
将它看做是一个 键: 值 对的集合
主要的操作
使用关键字存储和解析值
可以用 del 来删除一个键值对
list(d) 将返回包含该字典中所有键的列表
序列里创建字典
>>> dict([('sape', 4139), ('guido', 4127), ('jack', 4098)])
{'sape': 4139, 'guido': 4127, 'jack': 4098}
{'sape': 4139, 'guido': 4127, 'jack': 4098}
字典推导式
>>> {x: x**2 for x in (2, 4, 6)}
{2: 4, 4: 16, 6: 36}
{2: 4, 4: 16, 6: 36}
关键字参数来指定键值对
>>> dict(sape=4139, guido=4127, jack=4098)
{'sape': 4139, 'guido': 4127, 'jack': 4098}
{'sape': 4139, 'guido': 4127, 'jack': 4098}
示例
>>> tel = {'jack': 4098, 'sape': 4139}
>>> tel['guido'] = 4127
>>> tel
{'jack': 4098, 'sape': 4139, 'guido': 4127}
>>> tel['jack']
4098
>>> del tel['sape']
>>> tel['irv'] = 4127
>>> tel
{'jack': 4098, 'guido': 4127, 'irv': 4127}
>>> list(tel)
['jack', 'guido', 'irv']
>>> sorted(tel)
['guido', 'irv', 'jack']
>>> 'guido' in tel
True
>>> 'jack' not in tel
False
>>> tel['guido'] = 4127
>>> tel
{'jack': 4098, 'sape': 4139, 'guido': 4127}
>>> tel['jack']
4098
>>> del tel['sape']
>>> tel['irv'] = 4127
>>> tel
{'jack': 4098, 'guido': 4127, 'irv': 4127}
>>> list(tel)
['jack', 'guido', 'irv']
>>> sorted(tel)
['guido', 'irv', 'jack']
>>> 'guido' in tel
True
>>> 'jack' not in tel
False
循环的技巧
同时取出字典的键值
>>> knights = {'gallahad': 'the pure', 'robin': 'the brave'}
>>> for k, v in knights.items():
... print(k, v)
...
gallahad the pure
robin the brave
>>> for k, v in knights.items():
... print(k, v)
...
gallahad the pure
robin the brave
enumerate() 函数将索引位置和其对应的值同时取出
>>> for i, v in enumerate(['tic', 'tac', 'toe']):
... print(i, v)
...
0 tic
1 tac
2 toe
... print(i, v)
...
0 tic
1 tac
2 toe
zip() 函数匹配多个序列循环
>>> questions = ['name', 'quest', 'favorite color']
>>> answers = ['lancelot', 'the holy grail', 'blue']
>>> for q, a in zip(questions, answers):
... print('What is your {0}? It is {1}.'.format(q, a))
...
What is your name? It is lancelot.
What is your quest? It is the holy grail.
What is your favorite color? It is blue.
>>> answers = ['lancelot', 'the holy grail', 'blue']
>>> for q, a in zip(questions, answers):
... print('What is your {0}? It is {1}.'.format(q, a))
...
What is your name? It is lancelot.
What is your quest? It is the holy grail.
What is your favorite color? It is blue.
逆向循环一个序列
>>> for i in reversed(range(1, 10, 2)):
... print(i)
...
9
7
5
3
1
... print(i)
...
9
7
5
3
1
指定顺序循环
>>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']
>>> for f in sorted(set(basket)):
... print(f)
...
apple
banana
orange
pear
>>> for f in sorted(set(basket)):
... print(f)
...
apple
banana
orange
pear
想在循环时修改列表内容
新建一个列表进行存储,比较安全
>>> import math
>>> raw_data = [56.2, float('NaN'), 51.7, 55.3, 52.5, float('NaN'), 47.8]
>>> filtered_data = []
>>> for value in raw_data:
... if not math.isnan(value):
... filtered_data.append(value)
...
>>> filtered_data
[56.2, 51.7, 55.3, 52.5, 47.8]
>>> raw_data = [56.2, float('NaN'), 51.7, 55.3, 52.5, float('NaN'), 47.8]
>>> filtered_data = []
>>> for value in raw_data:
... if not math.isnan(value):
... filtered_data.append(value)
...
>>> filtered_data
[56.2, 51.7, 55.3, 52.5, 47.8]
深入条件控制
while 和 if 条件句中可以使用任意操作
校验一个值是否在(或不在)一个序列里
in 和 not in
比较两个对象是不是同一个对象
is 和 is not
比较操作可以传递
a < b == c 会校验是否 a 小于 b 并且 b 等于 c
比较操作
and
or
not
短路
如果 A 和 C 为真而 B 为假,那么 A and B and C 不会解析 C
序列和其它类型的比较
序列对象可以与相同类型的其他对象比较
首先比较两个序列的第一个元素,如果不同,那么这就决定了比较操作的结果。
如果它们相同,就再比较每个序列的第二个元素,以此类推,直到有一个序列被耗尽。
如果要比较的两个元素本身就是相同类型的序列,那么就递归进行字典顺序比较。如果两个序列中所有的元素都相等,那么我们认为这两个序列相等
7.输入输出
格式化输出
字符串前加上一个 f 或 F
>>> name = '小帅b'
>>> year = 2019
>>> f'{year}年,最帅的人是{name}'
'2019年,最帅的人是小帅b'
>>> year = 2019
>>> f'{year}年,最帅的人是{name}'
'2019年,最帅的人是小帅b'
str.format()
基本用法
>>> "The sum of 1 + 2 is {0}".format(1+2)
'The sum of 1 + 2 is 3'
'The sum of 1 + 2 is 3'
使用关键字参数
>>> print('This {food} is {adjective}.'.format(
... food='spam', adjective='absolutely horrible'))
This spam is absolutely horrible.
... food='spam', adjective='absolutely horrible'))
This spam is absolutely horrible.
位置
>>> print('{0} and {1}'.format('spam', 'eggs'))
spam and eggs
>>> print('{1} and {0}'.format('spam', 'eggs'))
eggs and spam
spam and eggs
>>> print('{1} and {0}'.format('spam', 'eggs'))
eggs and spam
'[]' 访问键
>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678}
>>> print('Jack: {0[Jack]:d}; Sjoerd: {0[Sjoerd]:d}; '
... 'Dcab: {0[Dcab]:d}'.format(table))
Jack: 4098; Sjoerd: 4127; Dcab: 8637678
>>> print('Jack: {0[Jack]:d}; Sjoerd: {0[Sjoerd]:d}; '
... 'Dcab: {0[Dcab]:d}'.format(table))
Jack: 4098; Sjoerd: 4127; Dcab: 8637678
'**' 符号将表作为关键字
>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678}
>>> print('Jack: {Jack:d}; Sjoerd: {Sjoerd:d}; Dcab: {Dcab:d}'.format(**table))
Jack: 4098; Sjoerd: 4127; Dcab: 8637678
>>> print('Jack: {Jack:d}; Sjoerd: {Sjoerd:d}; Dcab: {Dcab:d}'.format(**table))
Jack: 4098; Sjoerd: 4127; Dcab: 8637678
转化字符串
str()
返回人类可读的值
>>> s = 'Hello, world.'
>>> str(s)
'Hello, world.'
>>> str(s)
'Hello, world.'
repr()
生成解释器可读
>>> # The repr() of a string adds string quotes and backslashes:
... hello = 'hello, world\n'
>>> hellos = repr(hello)
>>> print(hellos)
'hello, world\n'
... hello = 'hello, world\n'
>>> hellos = repr(hello)
>>> print(hellos)
'hello, world\n'
':'
成为最小字符宽度
>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 7678}
>>> for name, phone in table.items():
... print(f'{name:10} ==> {phone:10d}')
...
Sjoerd ==> 4127
Jack ==> 4098
Dcab ==> 7678
>>> for name, phone in table.items():
... print(f'{name:10} ==> {phone:10d}')
...
Sjoerd ==> 4127
Jack ==> 4098
Dcab ==> 7678
'!a' 应用 ascii() ,'!s' 应用 str(),还有 '!r' 应用 repr():
>>> animals = 'eels'
>>> print(f'My hovercraft is full of {animals}.')
My hovercraft is full of eels.
>>> print(f'My hovercraft is full of {animals!r}.')
My hovercraft is full of 'eels'.
>>> print(f'My hovercraft is full of {animals}.')
My hovercraft is full of eels.
>>> print(f'My hovercraft is full of {animals!r}.')
My hovercraft is full of 'eels'.
%
>>> import math
>>> print('The value of pi is approximately %5.3f.' % math.pi)
The value of pi is approximately 3.142.
>>> print('The value of pi is approximately %5.3f.' % math.pi)
The value of pi is approximately 3.142.
手动格式化字符串
str.rjust()
左侧填充空格来对给定宽度的字段中的字符串进行右对齐
类似
str.ljust() 和 str.center()
str.zfill()
在数字字符串的左边填充零
读写文件
open() 返回一个 file object
f = open('workfile', 'w')
第一个参数
文件名
第二个参数
描述文件使用方式
'r'
只能读取
'w'
只能写入
'a'
追加内容
'r+'
打开文件进行读写
'b'
以 binary mode 打开文件
with
>>> with open('workfile') as f:
... read_data = f.read()
>>> f.closed
True
... read_data = f.read()
>>> f.closed
True
不需要手动close
文件对象的方法
f.read(size)
读取一些数据并将其作为字符串(在文本模式下)或字节对象(在二进制模式下)返回
size 被省略或者为负的时候
读取并返回文件的整个内容
f.readline()
从文件中读取一行
list(f) 或 f.readlines()
以列表的形式读取文件中的所有行
循环遍历文件读取行
>>> for line in f:
... print(line, end='')
...
This is the first line of the file.
Second line of the file
... print(line, end='')
...
This is the first line of the file.
Second line of the file
f.write(string)
把 string 的内容写入到文件中,并返回写入的字符数
f.tell()
返回文件读取指针的位置
f.seek()
f.seek(p, 0)
移动当文件第p个字节处
f.seek(p, 1)
移动到相对于当前位置之后的p个字节
f.seek(p, 2)
移动到相对文章尾之后的p个字节
使用 json 保存结构化数据
json.dumps
对象转json
json.loads
json转对象
9.类
名称和对象
多个名称(在多个作用域内)可以绑定到同一个对象
作用域(scope)
一个命名空间可直接访问的 Python 程序的文本区域
Python程序的几个作用域
最里面的局部作用域
外层函数的局部作用域
模块的全局作用域
包含Python内置对象的最外层作用域
global
作用于整个当前代码块的声明。 它意味着所列出的标识符将被解读为全局变量。
nonlocal
使得所列出的名称指向之前在最近的包含作用域中绑定的除全局变量以外的变量。
命名空间(namespace)
一个从名字到对象的映射
属性
在表达式 z.real 中,real 是对象 z 的一个属性。
生存期
内置名称的命名空间是在 Python 解释器启动时创建的,永远不会被删除
模块的全局命名空间在模块定义被读入时创建;通常,模块命名空间也会持续到解释器退出
一个函数的本地命名空间在这个函数被调用时创建,并在函数返回或抛出一个不在函数内部处理的错误时被删除。
例子
局部 赋值(这是默认状态)不会改变 scope_test 对 spam 的绑定
nonlocal 赋值会改变 scope_test 对 spam 的绑定
global 赋值会改变模块层级的绑定
初探类
类定义语法
class ClassName:
<statement-1>
.
.
.
<statement-N>
<statement-1>
.
.
.
<statement-N>
类对象
属性引用
obj.name
实例化
x = MyClass()
init初始化
>>> class Complex:
... def __init__(self, realpart, imagpart):
... self.r = realpart
... self.i = imagpart
...
>>> x = Complex(3.0, -4.5)
>>> x.r, x.i
(3.0, -4.5)
... def __init__(self, realpart, imagpart):
... self.r = realpart
... self.i = imagpart
...
>>> x = Complex(3.0, -4.5)
>>> x.r, x.i
(3.0, -4.5)
实例对象
属性
方法
方法对象
xf = x.f
while True:
print(xf())
while True:
print(xf())
类和实例变量
实例变量用于每个实例的唯一数据,而类变量用于类的所有实例共享的属性和方法
class Dog:
def __init__(self, name):
self.name = name
self.tricks = [] # creates a new empty list for each dog
def add_trick(self, trick):
self.tricks.append(trick)
>>> d = Dog('Fido')
>>> e = Dog('Buddy')
>>> d.add_trick('roll over')
>>> e.add_trick('play dead')
>>> d.tricks
['roll over']
>>> e.tricks
['play dead']
def __init__(self, name):
self.name = name
self.tricks = [] # creates a new empty list for each dog
def add_trick(self, trick):
self.tricks.append(trick)
>>> d = Dog('Fido')
>>> e = Dog('Buddy')
>>> d.add_trick('roll over')
>>> e.add_trick('play dead')
>>> d.tricks
['roll over']
>>> e.tricks
['play dead']
继承
单继承
class DerivedClassName(BaseClassName):
多重继承
class DerivedClassName(Base1, Base2, Base3):
私有变量
名称改写
__spam 被替换为:_classname__spam
有助于让子类重载方法而不破坏类内方法调用
迭代器
1、iter()
2、__next__()
3、__next__() 将引发 StopIteration 异常来通知终止 for 循环
生成器
generator
创造迭代器
返回数据时会使用 yield 语句
每次对生成器调用 next() 时,它会从上次离开位置恢复执行
生成器表达式
>>> sum(i*i for i in range(10)) # sum of squares
285
>>> xvec = [10, 20, 30]
>>> yvec = [7, 5, 3]
>>> sum(x*y for x,y in zip(xvec, yvec)) # dot product
260
>>> from math import pi, sin
>>> sine_table = {x: sin(x*pi/180) for x in range(0, 91)}
>>> unique_words = set(word for line in page for word in line.split())
>>> valedictorian = max((student.gpa, student.name) for student in graduates)
>>> data = 'golf'
>>> list(data[i] for i in range(len(data)-1, -1, -1))
['f', 'l', 'o', 'g']
285
>>> xvec = [10, 20, 30]
>>> yvec = [7, 5, 3]
>>> sum(x*y for x,y in zip(xvec, yvec)) # dot product
260
>>> from math import pi, sin
>>> sine_table = {x: sin(x*pi/180) for x in range(0, 91)}
>>> unique_words = set(word for line in page for word in line.split())
>>> valedictorian = max((student.gpa, student.name) for student in graduates)
>>> data = 'golf'
>>> list(data[i] for i in range(len(data)-1, -1, -1))
['f', 'l', 'o', 'g']
11.标准库简介 —— 第二部分
格式化输出
缩略显示
reprlib
美化输出:添加换行符和缩进
pprint
格式化文本段落
textwrap
将数字格式化为带有组分隔符的样式
locale
模板
占位符
$+标识符
>>> from string import Template
>>> t = Template('${village}folk send $$10 to $cause.')
>>> t.substitute(village='Nottingham', cause='the ditch fund')
'Nottinghamfolk send $10 to the ditch fund.'
>>> t = Template('${village}folk send $$10 to $cause.')
>>> t.substitute(village='Nottingham', cause='the ditch fund')
'Nottinghamfolk send $10 to the ditch fund.'
$$ 将被转义成单个字符 $
保留原有占位符
safe_substitute
自定义
class BatchRename(Template):
... delimiter = '%'
... delimiter = '%'
使用二进制数据记录格式
struct
多线程
threading
最好的使用方式
对资源的所有请求集中到一个线程中
使用 queue 模块向该线程供应来自其他线程的请求
日志
logging
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')
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')
弱引用
weakref
>>> import weakref, gc
>>> class A:
... def __init__(self, value):
... self.value = value
... def __repr__(self):
... return str(self.value)
...
>>> a = A(10) # create a reference
>>> d = weakref.WeakValueDictionary()
>>> d['primary'] = a # does not create a reference
>>> d['primary'] # fetch the object if it is still alive
10
>>> del a # remove the one reference
>>> gc.collect() # run garbage collection right away
0
>>> d['primary'] # entry was automatically removed
Traceback (most recent call last):
>>> class A:
... def __init__(self, value):
... self.value = value
... def __repr__(self):
... return str(self.value)
...
>>> a = A(10) # create a reference
>>> d = weakref.WeakValueDictionary()
>>> d['primary'] = a # does not create a reference
>>> d['primary'] # fetch the object if it is still alive
10
>>> del a # remove the one reference
>>> gc.collect() # run garbage collection right away
0
>>> d['primary'] # entry was automatically removed
Traceback (most recent call last):
用于操作列表的工具
存储类型一致的数据且存储密集更高
array
类似于列表,但从左端添加和弹出的速度较快,而在中间查找的速度较慢
collections
操作排序列表
bisect
基于常规列表来实现堆的函数
heapq
十进制浮点运算
用于十进制浮点运算
decimal
13. 接下来?
其他文档
Python 标准库
https://docs.python.org/zh-cn/3/library/index.html#library-index
安装 Python 模块
https://docs.python.org/zh-cn/3/installing/index.html#installing-index
Python 语言参考
https://docs.python.org/zh-cn/3/reference/index.html#reference-index
更多Python资源
Python网站
https://www.python.org
快速访问Python的文档
https://docs.python.org/
Python模块索引
https://pypi.org
代码示例集
https://code.activestate.com/recipes/langs/python/
Python相关的视频
http://www.pyvideo.org
Ecientific Python项目
https://scipy.org/
15. 浮点算术:争议和限制
争议和限制
大多数的十进制小数都不能精确地表示为二进制小数
对于大多数正常的浮点运算使用来说,你只需简单地将最终显示的结果舍入为你期望的十进制数值即可得到你期望的结果。
减少求和过程中的精度损失
math.fsum()
表示性错误
某些(其实是大多数)十进制小数无法以二进制(以 2 为基数的计数制)精确表示这一事实造成的错误
关于
作者
小帅b
公众号
学习python的正确姿势
收藏
收藏
0 条评论
下一页