zoukankan      html  css  js  c++  java
  • Effective Python

    Effective Python

    1.确认自己所用的Python版本

    优先使用python3,抛弃python2

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

    2.遵循PEP8风格指南

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

    绝对应该遵守的规则

    空格

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

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

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

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

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

    (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可知。

    8.不要使用包含两个以上表达式的列表推导

    列表支持多级循环,每一级循环也支持多项条件

    超过两个表达式的 列表推导不易理解,应尽量避免

    栗子1,遍历二维数组

    1 list1 = [[1, 2], [3, 4], [5, 6]]
    2 res1 = [x for row in list1 for x in row]
    3 print(res1) #[1, 2, 3, 4, 5, 6]

    栗子2,一维列表多条件

    1 list2 = [1, 2, 3, 4, 5, 6]
    2 res2 = [y for y in list2 if y > 4 and y % 2 == 0]
    3 print(res2) #[6]

    栗子3,根据二维数组来创建一个新的二维数组

    1 list3 = [[1, 2], [3, 4]]
    2 squares = [[x**2 for x in row] for row in list3]
    3 print(squares)  #[[1, 4], [9, 16]]

    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

    zip工作原理

    从每个迭代器中获取该迭代器的下一个元素,并将这些值汇聚成元祖,

    zip中受封装的迭代器一般长度都相等,只要有一个耗尽,zip就不会再产生

    元祖,所以zip中的迭代器一般长度都相等

    要点

    1.zip函数可以平行遍历多个迭代器

    2.python3中的zip相等于生成器,会在遍历过程中逐次产生元祖

    3.如果zip中提供的迭代长度不等,那么zip会自动提前终止

    4.itertools内置模块中的zip_longest函数可以平行迭代多个迭代器,而不用在乎它们的长度是否相等

    12.不要在for和while循环后写else代码块

    原因

    会令代码的可读性降低,不利于维护

    要点

    当整个循环主体都没遇到break语句时,循环后面的else代码块才会执行

  • 相关阅读:
    websocket1
    webpack 入门三
    weboack 入门二
    webpack 入门一
    输入一个url发生了什么
    http详解
    JavaScript对象详解
    javaScript垃圾回收机制
    js数据类型与隐式类型转换
    iOS证书申请、AppStore上架流程
  • 原文地址:https://www.cnblogs.com/marton/p/10902834.html
Copyright © 2011-2022 走看看