《Effective Python》笔记——第2章 函数

一、函数出错的时候抛异常,而不要返回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}

 

posted @ 2019-06-06 23:45  沄持的学习记录  阅读(173)  评论(0编辑  收藏  举报