book_effective Python_59个有效办法(二)

来源:互联网 发布:学生选课系统java实现 编辑:程序博客网 时间:2024/06/05 22:59

    • 二函数
      • 尽量用异常来表示特殊情况而不要返回None
      • 如何在闭包里使用外围作用域中的变量
      • 用生成器改写直接返回列表的函数
      • 在参数上面迭代时要多加小心
      • 数量可变的位置参数 args
      • 用关键字参数来表达可选的行为
      • 用None和文档字符串来描述具有动态默认值的参数
      • 用只能以关键字形式指定的参数来确保代码明晰

二、函数

14 尽量用异常来表示特殊情况,而不要返回None

  • None 和0及空字符之类的值,都评估为False,容易犯错

15 如何在闭包里使用外围作用域中的变量

这一条有点搞脑子
- 引用变量时,会从里到外遍历各个作用域。
- 变量赋值时,当前作用域内没有这个变量,会新定义这个变量,而不会向外遍历作用域。即,使用默认方式对闭包内的变量赋值,不会影响外围作用域中的同名变量。
- Python 3 ,在闭包内用nonlocal修饰某个名称,即可实现修改外围作用域中的同名变量;Python 2 ,可以使用可变值(例如,包含单个元素的列表)来实现。
- 尽量不要使用 nonlocal语句。

16 用生成器改写直接返回列表的函数

生成器是用yield表达式的函数。
例如,确定字符串的首字符索引

from itertools import islicedef index_word_iter(text):    if text:        yield 0    for index, letter in enumerate(text):        if letter == ' ':            yield index + 1address = 'Four score and...'result1 = list(index_word_iter(address))it = index_word_iter(address)result2 = list(islice(it, 0, 1))print result1print result2>>>[0, 5, 11]>>>[0]

17 在参数上面迭代时,要多加小心

虽但厉。好的,我会小心的。

18 数量可变的位置参数 *args

  • 在def语句中使用*args,即可令函数接受数量可变的位置参数。
  • 调用函数时,可以采用*操作符,把序列中的元素当成位置参数,传给该函数。
def log(message,*values):    pass

19 用关键字参数来表达可选的行为

  • 函数参数的指定可按位置或关键字
  • 关键字参数能够阐明每个参数的意图
  • 给函数添加新的行为时,可以使用带默认值的关键字参数,以便与原有的函数调用代码保持兼容
  • 可选的关键字参数,总是应该以关键字形式来指定

函数调用时,位置参数必须出现在关键字参数之前,每个参数只能指定一次。

20 用None和文档字符串来描述具有动态默认值的参数

  • 参数的默认值,只会在程序加载模块并读到本函数的定义时评估一次。对于{}或[]等动态的值,会导致奇怪的行为。
  • 对于以动态值作为实际默认值的关键字参数,应把默认值写为None,并在函数的文档字符串里面描述该默认值所对应的实际行为。
def decode(data,default=None):    ```Load JSON data from a string.    Args:        data:        default:...#描述    ```    if default is None:        default = {}    pass

21 用只能以关键字形式指定的参数来确保代码明晰

Python 3:参数列表里的 * 好标志这位置参数就此终结,之后的参数,只能以关键字形式来指定

def safe_division(number,divisor,*,io=False,iz=False):       passsafe_division(1,0,True,False)  #错误safe_division(1,0)  #正确,后面两个采用缺省值safe_division(1,0,iz=True) #正确

Python 2:没有明确地语法来定义只能以关键字形式指定的参数。不过,可以在参数列表中使用**操作符,并令函数在遇到无效的调用时抛出TypeErrors。 操作符**是用来接受任意数量的关键字参数,即使某些关键字没有定义在函数中,它也能接受。

def sd(n,d,**ks):    io=ks.pop('io',False)    iz=ks.pop('iz',False)    if ks:        raise TypeError('Unexpected **ks:%r' %ks)sd(1,0)sd(1,0,iz=True)sd(1,0,False) #会产生TypeError