https://www.python.org/dev/peps/pep-0008
用空格(space)表示缩进,而不要用制表符(tab)。
和语法相关的每一层缩进都用 4 个空格表示。
每行不超过 79 个字符。
对于占据多行的长表达式来说,除了首行之外的其余各行都应该在通常的缩进级别之上再加 4 个空格。
在同一份文件中,函数与类之间用两个空行隔开。
在同一个类中,方法与方法之间用一个空行隔开。
使用字典时,键与冒号之间不加空格,写在同一行的冒号和值之间应该加一个空格。
给变量赋值时,赋值符号的左边和右边各加一个空格,并且只加一个空格就好。
给变量的类型做注解(annotation)时,不要把变量名和冒号隔开,但在类型信息前应该有一个空格。
函数、变量、属性:lowercase_underscore
受保护的实例属性:_leading_underscore
私有的实例属性:**double_leading_underscore
类和异常:如:**double_leading_un
模块级别的常量:ALL_CAPS
类中的实例方法:应该把第一个参数命名为 self,用来表示该对象本身。
类方法的第一个参数:cls,表示类的本身
if not a is b
-> if a is not b
False
True
表示字符序列的两种类型:
Unicode 转二进制:str.encode
二进制数据转 Unicode 数据:bytes.decode
Unicode 三明治:编码和解码操作放在最外层,程序的核心部分可以使用 unicode 数据来运作(str 类型表示 unicode1 数据)。
辅助函数 1:bytes 转 str
def to_str(bytes_or_str:bytes) -> str:
if isinstance(bytes_or_str, str):
return bytes_or_str
else:
return bytes_or_str.decode()
辅助函数 2:str 转 bytes
def to_bytes(bytes_or_str: str) -> bytes:
if isinstance(bytes_or_str,bytes):
return bytes_or_str
else:
return bytes_or_str.encode()
bytes 类型、str 类型都可以使用+
运算符和进行比较,但是 bytes 和 str 之间不行,若比较 bytes 和 str 实例,始终返回False
with open() as f
的句柄默认需要使用 unicode 字符串操作,而不能采用原始的 bytes。
要注意当前操作系统的默认编码标准,获取该标准的方法:
python -c 'import locale; print(locale.getpreferredencoding())'
Python 3.6 添加了一种新的特性,叫作插值格式字符串(interpolated format string,简称 f-string)。
语法特性要求:在格式字符串前面加字母 f 作为前缀。
!
符号把值转换成 Unicode 及 repr 形式的字符串str.foramte
方法所支持的迷你语言。name = 'zhanghaohan'
value = 1.3256
places = 3
# name: zhanghaohan
print(f'name:{name}')
# 解决小数点之后位数的硬编码问题 1.33
print(f'{value:.{places}}')
# 清楚地表达逻辑 value:1
print(f'value:{round(value)}')
语法简洁的 Python 虽然可以写出很多浓缩的句式,但应该避免让这样的写法把表达式弄得太复杂。我们要遵循 DRY 原则,也就是不要重复自己写过的代码(Don’t Repeat Yourself)。
复杂的表达式,尤其是需要重复使用的表达式,应该写到辅助函数里。
if/else 结构写成的表达式比用 or、and 写成的 Boolean 表达式更好懂。
拆分(unpacking)可以把元组里面的元素分别赋给多个变量,这些变量可以修改。该方法比直接通过下标去访问元组内的元素更加清晰,需要的代码更少。
一行代码交换元素的原因:创建临时元组
a = 1
b = 2
a, b = b, a
unpacking 机制的另一个用法:在 for 循环或类似结构中,把复杂的数据拆分到相关的变量中。
temp = {
'1': ('a', 'b'),
'2': ('a', 'b'),
}
for key, (a, b) in temp.items():
print(key, a, b)
内置函数 enumerate:
案例:
my_son_list = [
'zhangchi',
'zhangshuai',
'zhangsan'
]
for index, son in enumerate(my_son_list):
print(index, son)
输出:
0 zhangchi
1 zhangshuai
2 zhangsan
有啥好处?
场景:需要同时遍历两份列表。
Python 内置的 zip 函数:
itertools.zip_longest
函数用法:
names = [
'zhangsan', 'lisi', 'wangwu'
]
ages = [
18, 19, 20
]
for name, age in zip(names, ages):
print(name, age)
输出:
zhangsan 18
lisi 19
wangwu 20
Python支持一个大多数语言都不支持的特性,即把 else 紧跟在整个循环的后面。
for-else
while
else 使用的场景:实现搜索逻辑,如判断两个数是否互质。
不建议在 for 和 while 后面使用 else 块,可以用如下两个方案替代
只要发现某个条件成立,就立刻返回,如果始终都没碰到这种情况,那么循环就会完整地执行,让程序返回函数末尾的那个值作为默认返回值。
用变量来记录循环过程中有没有碰到这样的情况,如果有,那就用 break 提前跳出循环,如果没有,循环就会完整地执行,无论如何,最后都返回这个变量的值。
a = b 是 a equals b
a := b 是 a walrus b
场景:只有 if-else 结构需要使用的变量
import random
def get_data():
return random.randrange(0, 100)
if (a := get_data()) > 10:
print(f'{a} > 10')
elif a < 10:
print(f'{a} < 10')