zoukankan      html  css  js  c++  java
  • python: 可变参数

    结论:定义Python函数的默认参数时,默认参数必须指向不变对象!

    事实上,编写程序时如 果可以设计成不变对象,就应该尽量设计成不变对象。

    以下例子来自 The Hitchhiker’s Guide to Python .

    假如定义函数:

    def append_to(element, to=[]):

        to.append(element)

        return to

    调用函数如下:

    my_list = append_to(12)

    print(my_list)

    my_other_list = append_to(42)

    print(my_other_list)

    我们可能期待这样的结果:

    [12]

    [42]

    实际上得到的是:

    [12]

    [12, 42]

    究其原因,是因为Python默认参数的值在函数定义时即已经算好了,而不会在再次调用时再重新计算。在上述例子中,默认参数to也是一个变量,它指向了对象[],每次函数调用时,如果对象的内容已经改变,那么默认参数to指向内容自然也变了。

    对List而言,List在定义时即被创立,只要名字不变,相同的List会一直被后续的调用使用,所以第二次调用时,得到的是已经被改变的List。

    想避免上述问题,不使用可变参数即可。

    假如真的需要传递一个List,可以使用如下方法:

    def append_to(element,to=None):

        if to is None:

            to=[]

        return to.append(element)

    ×上面表述多少有点易混淆,参数里的to和定义成List的to是否为不同的东西?它们是否指向了不同的地方?如果是,那么不应该使用同样的名字,因为那样容易使人以为两者是相同的。

    一些额外的扩展。

    这里设计到一个问题,即Python函数的参数是如何传递的?是call-by-name?还是call-by-reference?正确的说两者都不是,Python是call-by-object。

    Python有一句话很重要:Everything is an object.

    Python中“给一个变量赋值”,这里“变量”更准确的术语是names,“赋值”更准确的表述是“把name与一个object绑定起来”。

    请看以下例子体会Python与其他语言的区别:

    比如在C++中,

    string str=”ABC”;

    //…

    str=”DEF”;

    str指向内存中某一地址,该地址里面存的值是”ABC”;到后面,该内存里的内容被改写,变成”DEF”。

    下面看在Python中的情况,

    str=’ABC’

    #…

    str=’DEF’

    一开始把name str与一个字符串对象’ABC’绑定;到后面name str与另一个字符串对象’DEF’绑定,但是原先的’ABC’对象并不受影响。

    不难理解,一个object可以同时对应多个name。

    因此,在Python中无论赋值也好函数调用也好,所做的只是把”作用域”与”对象”绑定起来,如果该对象是可变的,那么它的变化会超出”作用域“之外。

    请看下面例子:

    def (ele):

        ele.append(1)

        ele=[2]

    m=[]

    f(m)

    print(m)

    结果会是[1]而不是[2],因为List是可变的,append方法改变了m,但是赋值局部变量ele的行为对外面作用域是没有影响的,Python中赋值是给name绑定一个新对象,而不是改变对象。

  • 相关阅读:
    动态加载方法(定时任务)
    安装 asp.net core 出错
    .NET:权限管理
    关于随机数
    博客园首弹
    C# MVC从其他系统获取文件流,显示文件
    Python中操作MySQL步骤
    MySql之_增删改查
    数据库之_SQL注入
    为什么上传到youtube上的视频很模糊
  • 原文地址:https://www.cnblogs.com/freshair_cnblog/p/10006526.html
Copyright © 2011-2022 走看看