近日一直在尝试用python写程序,看到一个现象很奇怪,百思不得其解,log下来和大家分享一下。

这是一个关于参数传递的问题

  1. 例子fun1
    def fun1 (out1):
        out1.add(1)

    >>> out=set([])
    >>> fun1(out)
    >>> out
    {1}
    我想这个结果对于大多数同学来说是可以接受的,因为在call fun1(out)时,形参out1实际被设成实参out(因为out不是简单类型)的引用,所以在fun1中对out1的操作实际上就是对实参out的操作,然后我们看到外部实参out的确被改变了。

  2. 例子fun2
    def fun2(out1):
        out1=set([])
        out1.add(1)

    >>> out=set([])
    >>> fun2(out)
    >>> out
    set()
    对比fun2和fun1,中间加了一行代码(黄色标识),对out1做简单赋值初始化;
    开头一直以为,fun1和fun2等价,out1赋初值就是对形参out1的操作,可是实际情况并非如此,这正是让我开始挠头的原因;
    我们从输出可以看见外部实参out并无改变。

  3. 分析
    也就是说,在加入了这行黄色代码后,fun2中的out1已经不再指向形参out1,而是变成了fun2的局部变量,out1指向了新的对象,当然对局部变量out1的操作也仅仅会影响新对象,并不会影响外部实参out的结果
  4. 解决办法
    如果想对集合out1做赋空值操作,请不要用上述黄色语句,而是使用out1.clear()

    >>> def fun3(out1):
        out1.clear()
        out1.add(1)

    >>> fun3(out)
    >>> out
    {1}

 

Technorati 标签: