一、函数出错的时候抛异常,而不要返回None
pass
二、闭包
书里的例子不好,参考https://www.cnblogs.com/Lin-Yi/p/7305364.html
在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用。这样就构成了一个闭包。
# outer是外部函数 a和b都是外函数的临时变量 def outer(a): b = 10 def inner(): #在内函数中 用到了外函数的临时变量 print(a+b) # 外函数的返回值是内函数的引用 return inner demo = outer(5) # outer()返回的是inner函数,用的是outer的变量a=5,b=10 demo() # 相当于print(5+10)
在内函数中想修改闭包变量(外函数绑定给内函数的局部变量)的时候:
python3中可以用nonlocal 关键字声明 一个变量, 表示需要向上一层作用域中找这个变量。
def outer(a): b = 10 def inner(): nonlocal a a = a + 1 print(a+b) return inner demo = outer(5) demo() # 相当于print(5+1+10)
三、用生成器来改写直接返回列表的函数
def index_words(text): # 返回字符串中单词首字母的index,并写入列表 result = [] if text: result.append(0) for index, letter in enumerate(text): if letter == ' ': result.append(index + 1) return result def index_words_yie(text): # 用生成器改写,数据量大时可以逐个处理 if text: yield 0 for index, letter in enumerate(text): if letter == ' ': yield index + 1 textdemo = 'abc bcd adg' res1 = index_words(textdemo) print(res1) res2 = index_words_yie(textdemo) print(list(res2))
四、用None和文档字符串来描述具有动态默认值的参数
如果参数是可变的,一定要用None作为形式上的默认值,不然多次执行函数时会产生异常。
from datetime import datetime from time import sleep def log1(message, when=datetime.now()): print('%s: %s' % (when, message)) log1('haha') sleep(1) log1('gaga') # 结果如下,时间没变,因为datetime.now()只在函数被定义的时候执行了一次 2019-06-09 22:23:19.039818: haha 2019-06-09 22:23:19.039818: gaga def log2(message, when=None): when = datetime.now() if when is None else when print('%s: %s' % (when, message)) log2('haha') sleep(1) log2('gaga') # 结果如下,函数定义时为None,函数执行时则会重新设置默认值。 2019-06-09 22:23:20.040858: haha 2019-06-09 22:23:21.041467: gaga
import json def decode(data,default={}): try: return json.loads(data) except ValueError: return default # 执行两次函数,都返回空字典 foo = decode('bad data') bar = decode('also bad') # 为各自的空字典插入键值 foo['foo'] = 1 bar['bar'] = 2 print(foo) print(bar) # 结果如下,两次执行函数,其实返回的是函数定义时生成的同一个字典,而不是各自独立生成一个新字典。 {'foo': 1, 'bar': 2} {'foo': 1, 'bar': 2} # 把默认值改成None def decode(data,default=None): if default is None: default = {} try: return json.loads(data) except ValueError: return default foo = decode('bad data') bar = decode('also bad') foo['foo'] = 1 bar['bar'] = 2 print(foo) print(bar) # 结果如下,两次执行函数,都各自生成了新的字典 {'foo': 1} {'bar': 2}