Effective Python - 用pythonic方式思考

Effective Python

1.确认本身所用的Python版本

优先使用python3,抛弃python2python

查看python版本信息: python --versiones6

 

2.遵循PEP8风格指南

采用一致的编码风格令代码更加易读,利于多人协做app

绝对应该遵照的规则ide

 

空格函数

(1)使用space来表示缩进,而不要使用tabui

(2)和语法相关的每一层缩进都用4个空格来表示编码

(3)每行的字符不该超过79es5

(4)对于多行长表达式,除了首行以外的其他各行都应该在一般的缩进级别之上再加4个空格spa

(5)文件中的函数与类之间应该用两个空行隔开3d

(6)同一个类中的两个方法之间应该用一个空行隔开

(7)在使用下标获取列表元素、调用函数或给关键字参数赋值时,不要在两旁添加空格

(8)为变量赋值时,赋值符号两边各添加一个空格

 

命名

(1)函数、变量及属性应该用小写字母来拼写,各单词间用下划线链接,如bub_sort

(2)受保护的实例属性,应以单下划线开头,如_name

(3)私有的实例属性,应以双下划线开头,如__name

(4)类与异常,应以每一个单词首字母大写的形式命名,如Note

(5)模块级别的常量,应所有采用大写字母拼写,单词之间用下划线链接,如ERR_CODE

(6)类中实例方法的首个参数,应该命名为self,表示该对象自身

(7)类方法的首个参数,应该命名为cls,表示该类自身

 

表达式和语句

(1)采用内联形式的否认词,不要把否认词放在整个表达式的前面,例如应该是 if a is not b 而不是if not a is b

(2)不要经过检测长度的办法,如len(list1) == 0来判断list1是否为[]或“”等空值,而是采用if not list1来判断,它会假定空值将自动评估为False

(3)检测list1是否为[1]或‘hi’等非空值,应用if list1语句会默认把非空的值判断为True

(4)不要编写单行的if语句、for循环、while循环及except复合语句,而是应该把这些语句分红多行来书写,以示清晰

(5)import语句应该老是放在文件开头

(6)引入模块的时候,老是应该使用绝对的名称,而不该该根据当前模块的路径来使用相对名称

  例如,引入bar包中的foo模块时,应该完整的写出from bar import foo,而不该该写import foo

(7)若是必定要用相对名称来编写import语句,应该采用明确的写法:from .import foo

(8)文件中的import语句应该按顺序划分红三个部分,分别表示标准模块、第三方模块以及自用模块。

  在每个部分中,各import'语句应该按模块的顺序来排列

 

5.了解切割序列的办法

(1)不要写多余的代码;当从索引开头获取元素,应把起始索引留空;当一直取到索引末尾,应把终止索引留空。

nums = [0, 1, 2, 3, 4, 5]
res1 = nums[:] #[0, 1, 2, 3, 4, 5]
res2 = nums[:3] #[0, 1, 2]
res3 = nums[3:] #[3, 4, 5]
res4 = nums[1:3] #[1, 2]
res5 = nums[2:-1] #[2, 3, 4]
res6 = nums[:-1] #[0, 1, 2, 3, 4]
res7 = nums[-2:] #[4, 5]
res8 = nums[-3:-1] #[3, 4]

 

(2)切片操做不计较开始索引和结束索引是否越界。

 利用这一特性,咱们能够限定输入序列的最大长度

nums = [_ for _ in range(30)]
first_ten_items = nums[:10]
#[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
last_ten_items = nums[-10:]
#[20, 21, 22, 23, 24, 25, 26, 27, 28, 29]

 

(3)对列表赋值时,若是使用切片操做,会把原列表中在相关范围内的值替换成新值,

位于切片以前和以后的值不变,列表会根据新值的个数相应的扩张和收缩。

nums = [0, 1, 2, 3, 4, 5]
nums_temp = nums
nums[:3] = ['a']
print(nums, nums is nums_temp) #['a', 3, 4, 5] True

 

来看个特殊的

nums = [0, 1, 2, 3, 4, 5]
nums_temp = nums
nums[:] = ['a', 'b', 'c']
print(nums, nums is nums_temp) #['a', 'b', 'c'] True

说明:把右侧的新值赋值一份去替换左侧列表的所有元素,但不会从新分配新的列表,这个从nums is nums_temp为True可知。

 

10.尽可能用enumerate取代range

1)range经常使用在一系列整数上的迭代

1 for i in range(10):
2     print(i)
View Code

 

2)对于字符串列表,可直接使用for...in迭代

1 fruits = ["apple", "banana", "pear"]
2 for ele in fruits:
3     print(ele)
View Code

 

3)对于迭代列表时,须要知道当前元素的索引

方式一:range

1 fruits = ["apple", "banana", "pear"]
2 for i in range(len(fruits)):
3     print("%d: %s" % (i, fruits[i]))
View Code

说明:代码有些生硬,必须先得到序列的长度,再经过下标访问元素,代码不免有些臃肿

 

方式二:enumerate

1 fruits = ["apple", "banana", "pear"]
2 for i, ele in enumerate(fruits):
3     print("%d: %s" % (i, ele))
View Code

 

要点:

1.再须要用到所遍历序列的索引时,通常用enumerate遍历

2.enumerate可指定开始计数的索引

 

11.用zip函数同时遍历两个迭代器

栗子:平行的迭代两个长度相等的列表,并求fruits中长度最长的元素

fruits = ["apple", "banana", "pear"]
letters = [len(fruit) for fruit in fruits]

 

方式一:经过某个列表的长度来执行循环

 1 fruits = ["apple", "banana", "pear"]
 2 letters = [len(fruit) for fruit in fruits]
 3 
 4 longest_name = None
 5 max_letters = 0
 6 
 7 for i in range(len(fruits)):
 8     if letters[i] > max_letters:
 9         max_letters = letters[i]
10         longest_name = fruits[i]
11 
12 print(max_letters)
13 print(longest_name)
View Code

 

方式二:经过enumerate来执行循环

 1 fruits = ["apple", "banana", "pear"]
 2 letters = [len(fruit) for fruit in fruits]
 3 
 4 longest_name = None
 5 max_letters = 0
 6 
 7 for i, fruit in enumerate(fruits):
 8     if letters[i] > max_letters:
 9         max_letters = letters[i]
10         longest_name = fruit
11 
12 print(max_letters)
13 print(longest_name)
View Code

 

方式三:用zip函数来执行循环

 1 fruits = ["apple", "banana", "pear"]
 2 letters = [len(fruit) for fruit in fruits]
 3 
 4 longest_name = None
 5 max_letters = 0
 6 
 7 for fruit, length in zip(fruits, letters):
 8     if length > max_letters:
 9         max_letters = length
10         longest_name = fruit
11 
12 print(max_letters)
13 print(longest_name)
View Code
相关文章
相关标签/搜索