了解python默认参数陷阱

    作者:课课家教育更新于: 2019-08-02 17:13:52

    大神带你学编程,欢迎选课
    Python是一种计算机程序设计语言。你可能已经听说过很多种流行的编程语言,比如非常难学的C语言,非常流行的java语言,适合初学者的Basic语言,适合网页编程的JavaScript语言等等。

    那Python是一种什么语言?

    首先,我们普及一下编程语言的基础知识。用任何编程语言来开发程序,都是为了让计算机干活,比如下载一个MP3,编写一个文档等等,而计算机干活的CPU只认识机器指令,所以,尽管不同的编程语言差异极大,最后都得“翻译”成CPU可以执行的机器指令。而不同的编程语言,干同一个活,编写的代码量,差距也很大。

    比如,完成同一个任务,C语言要写1000行代码,Java只需要写100行,而Python可能只要20行。

    所以Python是一种相当高级的语言。

    你也许会问,代码少还不好?代码少的代价是运行速度慢,C程序运行1秒钟,Java程序可能需要2秒,而Python程序可能就需要10秒。

    那是不是越低级的程序越难学,越高级的程序越简单?表面上来说,是的,但是,在非常高的抽象计算中,高级的Python程序设计也是非常难学的,所以,高级程序语言不等于简单。

    但是,对于初学者和完成普通任务,Python语言是非常简单易用的。连Google都在大规模使用Python,你就不用担心学了会没用。

    用Python可以做什么?可以做日常任务,比如自动备份你的MP3;可以做网站,很多著名的网站包括YouTube就是Python写的;可以做网络游戏的后台,很多在线游戏的后台都是Python开发的。总之就是能干很多很多事啦。

    Python当然也有不能干的事情,比如写操作系统,这个只能用C语言写;写手机应用,只能用Swift/Objective-C(针对iPhone)和Java(针对Android);写3D游戏,最好用C或C++。

    如果你是小白用户,满足以下条件:

    • 会使用电脑,但从来没写过程序;
    • 还记得初中数学学的方程式和一点点代数知识;
    • 想从编程小白变成专业的软件架构师;
    • 每天能抽出半个小时学习。

    不要再犹豫了,这个教程就是为你准备的!

    准备好了吗?

    学过函数的人一定听说过函数的默认参数,关于函数的默认参数,请看以下的例子:

    def extendList(val, lst=[]):
        lst.append(val)
        return lst
    list1 = extendList(10)
    list2 = extendList(123, [])
    print('list1 = %s' % list1)
    print('list2 = %s' % list2)

    打印的结果是?

    现在,我们将代码再添加一处,来看看最后的结果是什么?

    def extendList(val, lst=[]):
        lst.append(val)
        return lst
    list1 = extendList(10)
    list2 = extendList(123, [])
    list3 = extendList('a')
    print('list1=%s' % list1)
    print('list2=%s' % list2)
    print('list3=%s' % list3)

    当list1处调用函数时,10被加入了列表;list2处调用函数,123被加入到了新传入的列表中;最后到list3调用函数,应该将‘a’继续加入到列表中返回。因此得到的输出应该是:

    # list1 = [10]
    # list2 = [233]
    # list3 = ['a']

    0|1陷阱!

    然而,实际的打印结果变成了:

    了解python默认参数陷阱_python_python教程_21天学通python_课课家

    陷阱之所以称之为陷阱,代表我们不能以普通的思维来看待它,通过查阅资料,得到以下的一句解释:

    A new list is created once when the function is defined, and the same list is used in each successive call.

    在定义函数时,Python的默认参数会被计算一次,而不是每次调用函数时(比如Ruby)。这意味着如果你使用一个可变的默认参数并对其进行改变,那么你将会直接修改该对象,该影响将一直延续到未来关于该函数的调用(在默认参数没有被重新赋其他值的情况下)。

    众所周知,Python变量存储的是变量和值的引用关系,即实际变量对应一个内存地址。这意味着Python函数总是通过地址传递(传递参数)工作。调用函数时,不会将参数值复制到函数占位符。相反,我们将占位符指向变量本身。这有一个非常重要的结果:我们可以从函数内部更改变量的值。

     

    0|1如何避开陷阱?

    None通常是一个不错的选择:

    def extendList(val, lst = None):
        if not lst:
            lst = []
        lst.append(val)
        return lst

     有时您可以专门利用此陷阱来维护函数调用之间的状态。这通常在编写缓存函数时完成。

课课家教育

未登录