Python 3.8.2 官方文档学习笔记
入门知识与基本操作
Windows CMD 命令行交互运行 Python
启动 Python 环境
python
或者
py
在命令提示符中输入"Python"命令来启动Python解释器
python -V
查看Python版本
python3 xx.py
运行python脚本文件
python3 test.py arg1 arg2 arg3
sys.argv输出为:['test.py', 'arg1', 'arg2', 'arg3']
使用 sys.argv 来获取命令行参数
还可使用 getopt 模块
#!/usr/bin/python3
说明你想要用什么可执行程序去运行你这个文件中的代码
退出 Python 环境
quit() #注意:退出关闭 cmd 运行窗口命令是 exit
或者
Crtl + Z 然后回车
Windows CMD 窗口基本符号说明
> #单个大于符号,为 cmd 命令提示符,说明还没有进入 Python 环境,此时可以输入 python 或 py 进入 Python 环境。
>>> #三个大于符号,为 Python 命令提示符,说明已经在 Python 环境中了,可以输入任何 Python 语句。
... #三个点,为 Python 续行符,可以换行接着输入 Python 语句,例如用于 if 多行语句等。
Python 文件首行需说明编码方式
# -*- coding: utf-8 -*-
Python 标识符
- 第一个字符必须是字母或下划线 _ 。
- 标识符的其他的部分由字母、数字和下划线组成。
- 标识符对大小写敏感。
Python 保留字/关键字
import keyword
keyword.kwlist
['False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']
Python 字符串原始格式不转义
在字符串前面加上 r,表示 raw strings。
>>> print(r'C:\some\name') # note the r before the quote
C:\some\name
Python 多行语句
# -*- coding: utf-8 -*-
# 使用反斜杠(\)来实现多行语句,在 [], {}, 或 () 中的多行语句,不需要使用反斜杠(\)
total = item_one + \
item_two + \
item_three
输入输出
直接输出数据格式控制
f 或 F控制符
在字符串前面加上 f 或 F,在字符串中用 { } 将需要用的变量括起来即可。在变量名后可添加 '!a' , '!s' , '!r' 。'!a' 对变量应用 ascii(), '!s' 对变量应用 str(), and '!r' 对变量应用 repr()。
f'This is {变量名} written by {变量名}'
F'This is {变量名} written by {变量名!r}' # 使用了'!r'
name = 'soloman'
thing = 'python-notes'
print(f'This is {thing} written by {name}') # 输出:This is python-notes written by soloman
# { } 中数字冒号后可以控变量的输出格式,输入整数可以限制变量输出的宽度,输入小数可以控制小数保留的位数
import math
print(f'The value of pi is approximately {math.pi:.3f}.') # 输出:The value of pi is approximately 3.142.
# 在变量名后可添加 '!a' , '!s' , '!r' 。'!a' 对变量应用 ascii(), '!s' 对变量应用 str(), and '!r' 对变量应用 repr()。
animals = 'cat'
print(f'My hovercraft is full of {animals}.') #输出:My hovercraft is full of cat.
print(f'My hovercraft is full of {animals!r}.') # 使用'!r' 输出:My hovercraft is full of 'cat'.
str.format()
在字符串中用 { } 将数字括起来,这些数字用于对应变量的位置,也可以省略数字则按变量名顺序一一对应。在 format() 中给出对应变量名。
'字符串{0}字符串{1}字符串'.format(变量名1, 变量名2)
'字符串{变量名1}字符串{变量名2}字符串'.format(变量名1='变量值', 变量名2='变量值')
name = 'soloman'
thing = 'python-notes'
print('This is {0} written by {1}'.format(thing, name)) # 输出:This is python-notes written by soloman
print('This is {1} written by {0}'.format(thing, name)) # 输出:This is soloman written by python-notes
# { } 中数字冒号后可以控变量的输出格式,输入整数可以限制变量输出的宽度,输入小数可以控制小数保留的位数
pi = 3.141592653
print('Pi saves 3 float number is {0:.3f}'.format(pi)) # 输出:Pi saves 3 float number is 3.142
# 字典解包
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
% 格式控制符
字符串中的 % 后控制输出格式,字符串后的 % 跟要输出的变量名。
import math
print('The value of pi is approximately %5.3f' % math.pi) # 输出:The value of pi is approximately 3.142
str() 和 repr()
str() 输出适合人读的字符串格式,repr() 输出机器/编译器容易识别的字符串格式。
s = 'Hello, world.'
print(str(s)) # 输出:Hello, world.
print(repr(s)) # 输出:'Hello, world.'
文件读写控制
with open('filename', 'mode') as f:
# size 是一个可选的数字参数。 当 size 被忽略了或者为负, 那么该文件的所有内容都将被读取并且返回。
f.read(size)
# 从文件中读取一行。换行符为 '\n'。f.readline() 如果返回一个空字符串, 说明已经已经读取到最后一行。
f.readline()
# f.readlines() 将返回该文件中包含的所有行。如果设置可选参数 sizehint, 则读取指定长度的字节, 并且将这些字节按行分割。
f.readlines()
# f.write(string) 将 string 写入到文件中, 然后返回写入的字符数
f.write(string)
# f.tell() 返回文件对象当前所处的位置, 它是从文件开头开始算起的字节数。
f.tell()
# 如果要改变文件当前的位置, 可以使用 f.seek(offset, from_what) 函数。from_what 的值, 如果是 0 表示开头, 如果是 1 表示当前位置, 2 表示文件的结尾,from_what 值为默认为0,即文件开头
f.seek(offset, whence)
# 遍历文件所有行数据
for line in f:
print(line, end='')

json 数据文件读写
import json
json.dumps()
json.load()
数据类型
在 Python 中,变量就是变量,它没有类型,我们所说的"类型"是变量所指的内存中对象的类型。
Python3 中有六个标准的数据类型:
- Number(数字)
- String(字符串)
- List(列表)
- Tuple(元组)
- Set(集合)
- Dictionary(字典)
Python3 的六个标准数据类型中:
- 不可变数据(3 个):Number(数字)、String(字符串)、Tuple(元组);
- 可变数据(3 个):List(列表)、Dictionary(字典)、Set(集合)。
查询变量所指的对象类型
- type()不会认为子类是一种父类类型。
- isinstance()会认为子类是一种父类类型。
- type 是用于求一个未知数据类型对象,而 isinstance 是用于判断一个对象是否是已知类型。type 不认为子类是父类的一种类型,而isinstance会认为子类是父类的一种类型。可以用 isinstance 判断子类对象是否继承于父类,type 不行。综合以上几点,type 与 isinstance 虽然都与数据类型相关,但两者其实用法不同,type 主要用于判断未知数据类型,isinstance 主要用于判断 A 类是否继承于 B 类
1. 数字(Number)类型:整数、布尔型、浮点数和复数。
- int (整数), 如 1, 只有一种整数类型 int,表示为长整型,没有 python2 中的 Long。
- bool (布尔), 如 True。在 Python2 中是没有布尔型的,它用数字 0 表示 False,用 1 表示 True。到 Python3 中,把 True 和 False 定义成关键字了,但它们的值还是 1 和 0,它们可以和数字相加。
- float (浮点数), 如 1.23、3E-2
- complex (复数), 如 1 + 2j、 1.1 + 2.2j、用a + bj,或者complex(a,b)表示,复数的实部a和虚部b都是浮点型
- int(x) 将x转换为一个整数。
- float(x) 将x转换到一个浮点数。
- complex(x) 将x转换到一个复数,实数部分为 x,虚数部分为 0。
- complex(x, y) 将 x 和 y 转换到一个复数,实数部分为 x,虚数部分为 y。x 和 y 是数字表达式。
# 当字符串内容为浮点型要转换为整型时,无法直接用 int() 转换,需要把字符串先转化成 float 型再转换成 int 型
a='20.21'
print(int(float(a)))



2. 字符串(String)
- python中单引号和双引号使用完全相同。
- 转义符 ''反斜杠可以用来转义,使用r可以让反斜杠不发生转义。 如 r"this is a line with \n" 则\n会显示,并不是换行。
- 按字面意义级联字符串,如"this " "is " "string"会被自动转换为this is string。
- 字符串可以用 + 运算符连接在一起,用 * 运算符重复。
- Python 中的字符串有两种索引方式,从左往右以 0 开始,从右往左以 -1 开始。
- Python中的字符串不能改变。
- Python 没有单独的字符类型,一个字符就是长度为 1 的字符串。
Python转义字符:在需要在字符中使用特殊字符时,python 用反斜杠 \ 转义字符

字符串运算符: a 值为字符串 "Hello",b 变量值为 "Python"

Python字符串格式化

Python字符串内建函数

数据结构
1. 列表 list:列表被截取后返回一个包含所需元素的新列表。
列表相关方法
a = list() #创建一个空列表 a
或
a = []
a.append(x)
在列表 a 最后添加一个元素 x,相当于 a[len(a):] = [x]。该方法无返回值,但是会修改原来的列表。
a.clear()
清空列表,删除列表 a 中的所有元素,相当于 del a[:]。
a.copy()
返回列表 a 的浅拷贝,相当于返回 a[:]。
a.count(x)
返回元素 x 在列表 a 中出现的次数。
a.extend(iterable)
在列表 a 最后添加一个可迭代对象的所有元素,相当于 a[len(a):] = iterable。该方法没有返回值,但会在已存在的列表中添加新的列表内容。
a.index(x[, start[, end]])
返回元素 x 在列表 a 中的索引值,若列表 a 中不存在 x 则会报错 ValueError。可选参数 start end 用于限制 x 的搜索范围,即在 a 的一个子列表 a[start: end] 中搜素,但是返回的索引值是以整个列表 a 的首个元素开始计算,而不是以 start 计算。
a.insert(i, x)
在索引为 i 的元素前面插入元素 x 返回 None,所以 a.insert(0, x) 表示在列表 a 最前面插入元素 x,a.insert(len(a), x) 表示在列表 a 最后插入元素 x,相当于 a.append(x)。
a.pop([i])
移除并同时返回索引值 i 对应的元素值,如果没有给出索引值 a.pop() 默认移除并返回列表 a 的最后一个元素,若列表为空或 i 超出了索引范围则会报错 IndexError。
a.remove(x)
移除列表 a 中第一个出现的元素 x 返回 None,若没有元素值为 x 则会报错 ValueError。
a.reverse()
将列表中的元素反序重排。
a.sort(key=None, reverse=False)
将序列 a 升序排序,并返回 None,设置 reverse=True 则可降序排序。还可以给 key 传递一个函数,把每个列表元素带入函数运行,再根据结果排序。

补充:del 语句也可用于删除、清空列表,用下表索引来定位元素
a = [-1, 1, 66.25, 333, 333, 1234.5]
del a[0] # 删除元素
del a[2:5] # 删除元素
del a[:] # 清空整个列表,得到 a = []
del a # 删除列表 a 输入 a 会报错,因为此变量已经不存在了
列表实现堆栈(last-in, first-out)
stack = list()
stack.append(x) # 入栈
stack.pop() # 出栈
列表实现队列(first-in, first-out)
用列表的 a.insert(i, x) 和 a.pop([i]) 效率不高,速度很慢。一般用 collections.deque 实现队列。
from collections import deque
queue = deque(["Soloman", "Solomanxbr"]) # 创建队列
queue.append('www.soloman.vip') # 入队
queue.popleft() # 出队
列表推导式
一种更加高效、准确、方便的创建列表的方式。
列表 = [生成列表元素的语句]
squares = list(map(lambda x: x**2, range(10)))
squares = [x**2 for x in range(10)]
2. 元组 tuple
元组相关方法
t = tuple()
或
t = ()
t.count(x)
返回元素 x 在元组 t 中出现的次数。
t.index(x[, start[, end]])
返回元素 x 在元组 t 中的索引值,若元组 t 中不存在 x 则会报错 ValueError。可选参数 start end 用于限制 x 的搜索范围,即在 t 的一个子元组 t[start: end] 中搜素,但是返回的索引值是以整个元组 t 的首个元素开始计算,而不是以 start 计算。
元组内置函数

补充:元组特殊说明
元组为不可变序列类型,不能修改元素值,即不能进行赋值操作。 一个元素的元组一定要包含逗号,否则为字符串类型而不是元组:
t = ('Soloman',) # 用 type(t) 查看t类型为:元组
s = ('Soloman') # 用 type(s) 查看s类型为:字符串
3. 集合 set:集合是无序的不重复元素序列
集合相关方法
s = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}
# 创建空集合只能用 s = set(),不能用 s = {},因为这是创建了一个空字典
print(a - b) # a 和 b 的差集
print(a | b) # a 和 b 的并集
print(a & b) # a 和 b 的交集
print(a ^ b) # a 和 b 中不同时存在的元素
# 添加元素
s.add(x)
# 添加元素,且参数可以是列表,元组,字典等,x 可以有多个,用逗号分开
s.update(x)
# 将元素 x 从集合 s 中移除,如果元素不存在,则会发生错误
s.remove(x)
# 将元素 x 从集合 s 中移除,如果元素不存在,不会发生错误
s.discard(x)
# 清空集合 s
s.clear()
# 判断元素 x 是否在集合 s 中,存在返回 True,不存在返回 False。
x in s
s.copy()
s.difference()
s.difference_update()
s.intersection()
s.intersection_update()
s.isdisjoint()
s.issubset()
s.issuperset()
# 随机删除集合中的一个元素,set 集合的 pop 方法会对集合进行无序的排列,然后将这个无序排列集合的左面第一个元素进行删除。
s.pop()
s.symmetric_difference()
s.symmetric_difference_update()
s.union()
集合内置方法

补充:集合特殊说明
- 集合中所有元素都是独一无二的,没有重复元素,因此可用于去重。
- 集合中所有元素都是无序排列的。
- 跟列表推导式类似,也有集合推导式
集合 = {生成集合元素的语句}
s = {x for x in 'abracadabra' if x not in 'abc'} # 得到集合 s = {'r', 'd'}
4. 字典 dict:字典是无序的对象集合
字典相关方法
d = {'name': 'Soloman', 'wechat_id': 'Solomanxbr', 'website': 'www.soloman.vip'}
print (d.keys()) # 输出所有键
print (d.values()) # 输出所有值
# keys和values都是只读的
d.clear() # 清空字典,该函数没有任何返回值。
字典内置函数&方法

5. 数据遍历技术
序列类型(列表、元组、集合)数据的遍历
使用 enumerate() 方法同时获取序列的元素索引和元素值。
a = ['tic', 'tac', 'toe']
for i, v in enumerate(a):
print(i, v)
使用 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))
使用 sorted() 方法按排序顺序遍历序列的元素值。sorted() 会返回一个新的排序后的列表,原始列表不会被改变。
basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']
for f in sorted(set(basket)):
print(f)
使用 reversed() 方法反序遍历序列元素。
for i in reversed(range(1, 10, 2)):
print(i)
键值对类型(字典)数据的遍历
使用字典的 item() 方法同时获取键和值。
knights = {'gallahad': 'the pure', 'robin': 'the brave'}
for k, v in knights.items():
print(k, v)
Python 运算符
算术运算符
# 加减乘除,除法 / 总是返回一个浮点数
+ - * /
# 取模 - 返回除法的余数
%
# 幂 - 返回x的y次幂
**
# 取整除 - 向下取接近商的整数,// 得到的并不一定是整数类型的数,它与分母分子的数据类型有关系。
//
>>> 7//2
3
>>> 7.0//2
3.0
比较运算符
>
<
==
>=
<=
!=
赋值运算符
=
+=
-=
*=
/=
# 取模赋值运算符
%=
# 幂赋值运算符
**=
# 取整除赋值运算符
//=
# 海象运算符,可在表达式内部为变量赋值。Python3.8 版本新增运算符。在这个示例中,赋值表达式可以避免调用 len() 两次
:=
if (n := len(a)) > 10:
print(f"List is too long ({n} elements, expected <= 10)")
位运算符:按位运算符是把数字看作二进制来进行计算
a = 0011 1100
b = 0000 1101

成员运算符和身份运算符
# 成员运算符,判断一个元素是否在某个序列中
in # 如果在指定的序列中找到值返回 True,否则返回 False。
not in # 如果在指定的序列中没有找到值返回 True,否则返回 False。
# 身份运算符,判断两个对象是否是同一个对象
is # is 是判断两个标识符是不是引用自一个对象 x is y, 类似 id(x) == id(y) , 如果引用的是同一个对象则返回 True,否则返回 False
is not # is not 是判断两个标识符是不是引用自不同对象 x is not y , 类似 id(a) != id(b)。如果引用的不是同一个对象则返回结果 True,否则返回 False。
is 用于判断两个变量引用对象是否为同一个, == 用于判断引用变量的值是否相等。
逻辑运算符
not
and
or
a = 10
b = 20

几大运算符的优先级说明:
数值运算符 》比较运算符 》布尔运算符(not 》and 》or)
Python数据类型转换
这些函数返回一个新的对象,表示转换的值

函数
- return [表达式] 结束函数,选择性地返回一个值给调用方,不带表达式的 return 相当于返回 None。Python 函数可以返回多个值,多个值以tuple元组的方式返回

参数的定义和传递
1. 默认值参数
每个参数都有一个默认值,即使调用函数时不传递实参也可以,那就会直接使用默认值。
def my_webiste(name='Soloman', url='www.soloman.vip', developer='Solomanxbr'):
print('欢迎访问由{0}开发的网站{1},网站地址是:{2}'.format(name, developer, url))
2. 关键字参数
每个参数都有一个名字,传递参数时可以通过键值对的形式,给每个参数传递对应的值。
def my_webiste(name, url='www.soloman.vip', developer='Solomanxbr'):
print('欢迎访问由{0}开发的网站{1},网站地址是:{2}'.format(name, developer, url))
my_webiste(name='Soloman', url='https://www.soloman.vip')
3. 位置参数
按照位置顺序来传递的参数,可以是默认值参数或者关键字参数。
def my_webiste(name, url, developer):
print('欢迎访问由{0}开发的网站{1},网站地址是:{2}'.format(name, developer, url))
my_webiste(name='Soloman', 'https://www.soloman.vip', 'Solomanxbr') #函数调用后得到:name='Soloman', url='https://www.soloman.vip', developer='Solomanxbr'
4. 多个未知参数
当我们不确定函数会接收到多少个参数时,可以用 *args 接收多余的位置参数,得到一个由这些多余的位置参数组成的元组;可以用 **kwargs 接收多余的关键字参数,得到一个由这些多余的关键字参数组成的字典。若要提取其中元素,需用拆包。
def about_me(name, wechat_id, age='22', *args, **kwargs):
print('关于我')
about_me('Soloman', 'Solomanxbr', '24', '男', '大学生', honor='国家奖学金', hobby='python')
#函数调用后得到:
name='Soloman', wechat_id='Solomanxbr', age='24',
args=('男', '大学生'),
kwargs={honor:'国家奖学金', hobby:'python'}
5. 定义函数时的参数选择
# 一般的完整函数定义为:
def complete_func(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2, *args, **kwargs):
pass
# 其中,/ 前只能是位置参数,不能使用关键字参数的形式传递参数,* 后只能是关键字参数(当然不包括 *args 和 **kwargs),在 / 和 * 之间可以是位置参数或者关键字参数。
# 只要函数形参定义中没有 / 和 * ,则可以通过位置或关键字任一种方式传递参数
def pos_kwd_func(name, wechat, qq, weibo='Soloman'):
print('两种参数传递方式均可')
pos_kwd_func('Soloman', 'Solomanxbr', '778666985', 'Soloman')
或者
pos_kwd_func(name='Soloman', wechat='Solomanxbr', qq='778666985', weibo='Soloman')
或者
pos_kwd_func('Soloman', 'Solomanxbr', qq='778666985', weibo='Soloman')
# 只要函数形参定义中有 / ,则 / 之前的参数只能通过位置参数方式传递参数
def pos_only_func(name, age, gender, /):
print('只能通过位置参数方式传递参数')
pos_only_func('Soloman', '22', 'boy') # 用其它方式调用均会报错
# 只要函数形参定义中有 * ,则 * 之后的参数只能通过关键字参数方式传递参数
def kwd_only_func(*, name, school, student_id):
print('两种参数传递方式均可')
kwd_only_func(name='Soloman', school='MIT', student_id='20200001') # 用其它方式调用均会报错
6. 函数的文档说明字符串
def test():
'''函数说明文字'''
print(test.__doc__) # 获取函数说明文字
参数调用的返回值
没有写 return 或者 只写了 return,都会只返回 None。 写了 return 表达式,才有正确返回值。
Python 条件控制语句
- 在Python中没有switch – case语句
- 在 Python 中没有 do..while 循环
Python 迭代器与生成器
迭代器
迭代器有两个基本的方法:iter() 和 next()。
list=[1,2,3,4]
it = iter(list) # 创建迭代器对象
print(next(it)) # 输出迭代器的下一个元素
创建一个迭代器
把一个类作为一个迭代器使用需要在类中实现两个方法 iter() 与 next() 。 iter() 方法返回一个特殊的迭代器对象, 这个迭代器对象实现了 next() 方法并通过 StopIteration 异常标识迭代的完成。 next() 方法会返回下一个迭代器对象。 StopIteration 异常用于标识迭代的完成,防止出现无限循环的情况,在 next() 方法中我们可以设置触发 StopIteration 异常来结束迭代。
class MyNumbers:
def __iter__(self):
self.a = 1
return self
def __next__(self):
if self.a <= 20:
x = self.a
self.a += 1
return x
else:
raise StopIteration
生成器
在 Python 中,使用了 yield 的函数被称为生成器(generator)。生成器是一个返回迭代器的函数,只能用于迭代操作 yield 的作用就是把一个函数变成一个 generator,带有 yield 的函数不再是一个普通函数,Python 解释器会将其视为一个 generator yield后面可以加多个数值(可以是任意类型),但返回的值是元组类型的。
文件结构和引用关系
1. 模块 module
A module is a file containing Python definitions and statements. The file name is the module name with the suffix .py appended. 简单来说,一个 python 模块就是一个 python 的 .py 文件,文件名就是模块名。
import soloman # 导入模块soloman
import soloman as solo # 导入模块soloman,取别名 solo
from soloman import man # 从模块soloman中导入函数man,注意模块soloman未被导入
from soloman import man as m # 从模块soloman中导入函数man,取别名 m
from soloman import * # 导入模块soloman的所有函数
# 在模块内部可以通过变量 __name__ 获取模块名。以下代码让模块自己运行时或者作为脚本运行时可以执行代码,而作为模块导入时不执行代码。因为当模块自己运行时或者作为脚本运行时 __name__ 被赋值为 '__main__',而作为模块导入时 __name__ 被赋值为模块名。
if __name__ == '__main__':
xxx
注意:若一个导入的模块被修改,只有重启编译器才能有效。因此,若需要交互式测试一个模块请用模块重载方法 importlib.reload()
import importlib
importlib.reload(modulename)
在其他文件中导入自己的模块xxx.py
import sys
sys.path.append("模块xxx.py所在的文件夹路径")
import xxx
Python 编译文件
为了加载模块时更快,每个模块都会缓存有该模块的编译文件,在模块同级目录下的 __pycache__/module.version.pyc
__pycache__ 为模块同级目录下的文件夹名称
module 为模块名,version 为所安装 Python 的版本
例如:我安装的Python版本为3.8。则 soloman.py 模块的编译文件命名为 soloman.cpython-38.pyc
dir() 函数
dir() 函数用于返回一个模块中定义过的所有变量名称,包括变量、函数名、模块名等等。
>>> dir(sys)
['__displayhook__', '__doc__', '__excepthook__', '__loader__', '__name__', '__package__', '__stderr__', '__stdin__', '__stdout__', '_clear_type_cache', '_current_frames', '_debugmallocstats', '_getframe', '_home', '_mercurial', '_xoptions', 'abiflags', 'api_version', 'argv', 'base_exec_prefix', 'base_prefix', 'builtin_module_names', 'byteorder', 'call_tracing', 'callstats', 'copyright', 'displayhook', 'dont_write_bytecode', 'exc_info', 'excepthook', 'exec_prefix', 'executable', 'exit', 'flags', 'float_info', 'float_repr_style', 'getcheckinterval', 'getdefaultencoding', 'getdlopenflags', 'getfilesystemencoding', 'getobjects', 'getprofile', 'getrecursionlimit', 'getrefcount', 'getsizeof', 'getswitchinterval', 'gettotalrefcount', 'gettrace', 'hash_info', 'hexversion', 'implementation', 'int_info', 'intern', 'maxsize', 'maxunicode', 'meta_path', 'modules', 'path', 'path_hooks', 'path_importer_cache', 'platform', 'prefix', 'ps1', 'setcheckinterval', 'setdlopenflags', 'setprofile', 'setrecursionlimit', 'setswitchinterval', 'settrace', 'stderr', 'stdin', 'stdout', 'thread_info', 'version', 'version_info', 'warnoptions']
# 直接用 dir() 会列出当前定义过的所有名称,但不会列出内建函数和变量,如有需要,可通过内建模块 builtins 来查询。
import builtins
>>> dir(builtins)
['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BlockingIOError', 'BrokenPipeError', 'BufferError', 'BytesWarning', 'ChildProcessError', 'ConnectionAbortedError', 'ConnectionError', 'ConnectionRefusedError', 'ConnectionResetError', 'DeprecationWarning', 'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False', 'FileExistsError', 'FileNotFoundError', 'FloatingPointError', 'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError', 'ImportWarning', 'IndentationError', 'IndexError', 'InterruptedError', 'IsADirectoryError', 'KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'NameError', 'None', 'NotADirectoryError', 'NotImplemented', 'NotImplementedError', 'OSError', 'OverflowError', 'PendingDeprecationWarning', 'PermissionError', 'ProcessLookupError', 'ReferenceError', 'ResourceWarning', 'RuntimeError', 'RuntimeWarning', 'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'TimeoutError', 'True', 'TypeError', 'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning', 'ValueError', 'Warning', 'ZeroDivisionError', '_', '__build_class__', '__debug__', '__doc__', '__import__', '__name__', '__package__', 'abs', 'all', 'any', 'ascii', 'bin', 'bool', 'bytearray', 'bytes', 'callable', 'chr', 'classmethod', 'compile', 'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'exec', 'exit', 'filter', 'float', 'format', 'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'isinstance', 'issubclass', 'iter', 'len', 'license', 'list', 'locals', 'map', 'max', 'memoryview', 'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', 'quit', 'range', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted','staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'vars', 'zip']
2. 包 package
Python 包是一个包含了多个Python文件或文件夹的文件夹。里面必须包含 init.py 文件,用以说明该文件夹是一个 Python 包。
# 这种直接链式导入的方式,前面几级只能是 Python 包,最后一级只能是 Python 模块或者包。不能是模块中定义的函数、变量等。
import item.subitem.subsubitem
# 这种从包导入的方式,前面几级只能是 Python 包,但最后一级还可以是 Python 模块或者包、函数、类、变量等。
from package import item
# 这种方式并不会将 Python 包中所有文件导入,而是只导入 __init__.py 文件中变量 __all__ = ["echo", "surround", "reverse"] 中包含的模块名,如果 __init__.py 文件没有定义变量 __all__ 则只会导入当前包 package 和当前包中定义的变量等(即在 __init__.py 中定义的变量),不会导入包中所有文件。要区别于模块的导入(from soloman import * 能够导入模块soloman的所有函数)
from package import *
异常和错误
语法错误 SyntaxError
说明你的程序存在 Python 语法错误,初学者容易犯此错
异常处理 Exceptions
# except 后面可跟多个错误类型,用元组表示(圆括号括起来即可)。else 语句只有当 try 语句运行无错误时才会被执行,finally 语句任何情况下总会被执行。Python 使用 raise 语句抛出一个指定的异常
try:
pass
raise NameError('HiThere')
except (RuntimeError, TypeError, NameError):
pass
raise
else:
pass
finally:
pass

断言 assert
# Python assert(断言)用于判断一个表达式,在表达式条件为 false 的时候触发异常。断言可以在条件不满足程序运行的情况下直接返回错误,而不必等待程序运行后出现崩溃的情况,例如我们的代码只能在 Linux 系统下运行,可以先判断当前系统是否符合条件。
assert expression
if not expression:
raise AssertionError
assert expression [, arguments]
if not expression:
raise AssertionError(arguments)
import sys
assert ('linux' in sys.platform), "该代码只能在 Linux 下执行"
面向对象
类的私有属性
__private_attrs:两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问。在类内部的方法中使用时 self.__private_attrs。
类的方法
在类的内部,使用 def 关键字来定义一个方法,与一般函数定义不同,类方法必须包含参数 self,且为第一个参数,self 代表的是类的实例。
类的私有方法
__private_method:两个下划线开头,声明该方法为私有方法,只能在类的内部调用 ,不能在类的外部调用。self.__private_methods。
类的专有方法
__init__ : 构造函数,在生成对象时调用
__del__ : 析构函数,释放对象时使用
__repr__ : 打印,转换
__setitem__ : 按照索引赋值
__getitem__: 按照索引获取值
__len__: 获得长度
__cmp__: 比较运算
__call__: 函数调用
__add__: 加运算
__sub__: 减运算
__mul__: 乘运算
__truediv__: 除运算
__mod__: 求余运算
__pow__: 乘方
Python3 中类的静态方法、普通方法、类方法
-
静态方法: 用 @staticmethod 装饰的不带 self 参数的方法叫做静态方法,类的静态方法可以没有参数。类和对象访问,不能和其他方法重名,不然会相互覆盖,后面定义的会覆盖前面的
-
普通方法/实例方法: 默认有个self参数,且只能被对象调用。
-
类方法: 默认有个 cls 参数,需要加上 @classmethod 装饰器。类和对象访问,不能和其他方法重名,不然会相互覆盖,后面定义的会覆盖前面的
-
私有方法:两个下划线开头,只能在类内部访问
-
多继承情况下:从左到右查找方法,找到为止,不然就抛出异常
class Classname:
@staticmethod
def a():
print('静态方法')
@classmethod
def b(cls):
print('类方法')
# 普通方法
def c(self):
print('普通方法/实例方法')
Python3 中多继承遵循广度优先原则,涉及到查找顺序(MRO)
class A:
def __init__(self):
print("Enter A")
print(self)
print("Leave A")
class B(A):
def __init__(self):
print("Enter B")
print(self)
super(B, self).__init__()
print("Leave B")
class C(A):
def __init__(self):
print("Enter C")
print(self)
super(C, self).__init__()
print("Leave C")
class D(B, C):
def __init__(self):
print("Enter D")
print(self)
super(D, self).__init__()
print("Leave D")
d = D()
# 结果如下:
Enter D
<__main__.D object at 0x7fdb02618490>
Enter B
<__main__.D object at 0x7fdb02618490>
Enter C
<__main__.D object at 0x7fdb02618490>
Enter A
<__main__.D object at 0x7fdb02618490>
Leave A
Leave C
Leave B
Leave D
命名空间和作用域
命名空间
-
内置名称(built-in names), Python 语言内置的名称,比如函数名 abs、char 和异常名称 BaseException、Exception 等等。
-
全局名称(global names),模块中定义的名称,记录了模块的变量,包括函数、类、其它导入的模块、模块级的变量和常量。
-
局部名称(local names),函数中定义的名称,记录了函数的变量,包括函数的参数和局部定义的变量。(类中定义的也是)
-
查找顺序为:局部的命名空间 -> 全局命名空间 -> 内置命名空间。

作用域
Python 中只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域,其它的代码块(如 if/elif/else/、try/except、for/while等)是不会引入新的作用域的,也就是说这些语句内定义的变量,外部也可以访问
-
L(Local):最内层,包含局部变量,比如一个函数/方法内部。
-
E(Enclosing):包含了非局部(non-local)也非全局(non-global)的变量。比如两个嵌套函数,一个函数(或类) A 里面又包含了一个函数 B ,那么对于 B 中的名称来说 A 中的作用域就为 nonlocal。
-
G(Global):当前脚本的最外层,比如当前模块的全局变量。
-
B(Built-in): 包含了内建的变量/关键字等。,最后被搜索
-
规则顺序: L –> E –> G –>B。在局部找不到,便会去局部外的局部找(例如闭包),再找不到就会去全局找,再者去内置中找。
global 和 nonlocal关键字
当内部作用域想修改外部作用域的变量时,就要用到global和nonlocal关键字了。
# 修改全局变量
num = 1
def fun1():
global num # 需要使用 global 关键字声明
print(num)
num = 123
print(num)
fun1()
print(num)
# 修改非局部非全局变量(嵌套层的变量)
def outer():
num = 10
def inner():
nonlocal num # nonlocal关键字声明
num = 100
print(num)
inner()
print(num)
outer()
附:Python常用函数
eval()
repr()
map()
filter()
lambda
from functools import reduce
reduce()
type()
dir()
getattr()
hasattr()
isinstance()