一:变量
1:变量名要有描述性,不能太宽泛
- 例如表示这周的周几: day与day_of_week,我们更喜欢第二种。
2:变量名最好让人猜出类型:
- 1 : 布尔类型的变量我们命名最好以is, has等非黑即白的词语修饰。
- is_supuser
- has_error
- allow_vip
- use_msgpack
- debug
- 2: **数字类型,**语义是否包含数量,是否以_id结尾,如果不是尽量使用length, count等数量的词作为开头或者结尾。
- port(语义包含)
- user_id(以_id结尾)
- length_of_username(以length开头)
- max_length(以length结尾)
3: 匈牙利命名法
-
变量类型的缩写,放在变量的最前面。
-
pl_students, p指的是Persion是students的类型,l指的是list, 表示这个变量是list类型。
4:变量名其他注意事项
- 1:变量名应控制在两三个词左右。
- 2: 同一段代码中,不应该出现相似的变量名: user1, user2,user3。
- 3: 不能使用含有否定意义的变量名:is_not_normal。我们完全可以使用is_special来代替。
三: 数字与字符串使用技巧:
1: 少写数字字面量,多使用枚举:
from enum import IntEnum
class TripSource(IntEnum):
FROM_WEBSITE = 11
FROM_IOS_CLIENT = 12
def mark_trip_as_featured(trip):
if trip.source == TripSource.FROM_WEBSITE:
do_some_thing(trip)
elif trip.source == TripSource.FROM_IOS_CLIENT:
do_some_other_thing(trip)
... ...
return
2: 改善字符串的可读性:
- 使用括号将长字符串包起来,然后就可以随意折行了
s = (
"There is something really bad happened during the process. "
"Please contact your administrator."
)
3: 使用“无穷大” float(“inf”)
4: “value += 1” 并非线程安全
四: 容器的门道
1 : 避免频繁的扩充列表和创建新列表:
-
1:多使用yield关键字,返回生成器对象。
-
2: 使用生成器表达式代替列表推导式。
- 生成器表达式: (i for i in range(100))
-
3: 尽量使用模块提供的懒惰对象:
- re.finditer 代替re.findall
- 直接使用可迭代对象: for line in fp 而不是for line in fp.readlines()
2: 列表的头部操作使用deque:
- 列表底层是数组,对于头部插入数据,后面的都要移动,时间复杂度是O(N)。
- 如果我们创建的列表,经常需要在头部插入数据,则考虑使用双端队列,而不是列表。
- from collections import deque
3: 判断是否存在方面—集合或者字典优于列表
- 集合和字典底层都是哈希表,查找只需要O(1),而列表是O(N)。
4: 高层看容器:
-
python中的容器,实际上只是实现了collections模块下的abc模块中抽象类的组合体。
5: 高效的动态解包:
-
例如合并字典:
user = {**{"name": "piglei"}, **{"movies": ["Fight Club"]}}
6: next()函数的使用:
- next(), 接收可迭代对象。可以得到迭代器的下一个元素。
- 适用场景: 从列表中查询第一个满足条件的成员。
7: 使用有序字典去重:
-
字典和集合的结构特点保证了它们的成员不会重复,所以它们经常被用来去重。但是,使用它们俩去重后的结果会丢失原有列表的顺序。
-
注意: python3.6版本以上的,字典就是有序的了,就不用下面的方式了。
-
需求:去重还要保留原始顺序。
from collections import OrderedDict my_list = [1, 2, 1, 3, 4, 7, 5] print(list(OrderedDict.fromkeys(my_list).keys()))
8: 迭代器枯竭问题:
- 迭代器对象只能被遍历一次,第二次啥也不输出了。
9: 循环体内不能修改可迭代对象:
- 遍历的下标在不断增长,而列表本身的长度同时又在不断缩减。这样就会导致列表里的一些成员其实根本就没有被遍历到