• 《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}
  • 相关阅读:
    STL的相关知识
    有关欧拉通路/回路的一些资料整理
    差分约束
    BZOJ 2100: [Usaco2010 Dec]Apple Delivery
    BZOJ 2017: [Usaco2009 Nov]硬币游戏(A Coin Game)
    vijos 1282&1283&1284&1285 佳佳的魔法照片/魔法药水/魔杖/魔法阵
    BZOJ 1660: [Usaco2006 Nov]Bad Hair Day
    BZOJ 1602: [Usaco2008 Oct]牧场行走
    BZOJ 1647: [Usaco2007 Open]Fliptile 翻格子游戏
    BZOJ 1646: [Usaco2007 Open]Catch That Cow
  • 原文地址:https://www.cnblogs.com/maxgongzuo/p/10987323.html
Copyright © 2020-2023  润新知