python学习——python函数参数变化问题

昨天写LeetCode的时候,发现python跟C++不一样的地方,导致思路没有错,代码运行就报错。

参考博客:http://www.cnblogs.com/monkey-moon/p/9347505.html

入门学习编程的时候,我们都学过swap函数,就是传入两个参数,交换两个参数,这个swap函数在C语言中给我们的警示是函数内改变传入的参数值是不会改变函数外的值,如果不用引用和指针的话。但是在python中,有可变对象和不可变对象之分。只有传入的是不可变对象时,值才不发生改变,若是可变对象,充当函数参数时要注意了。

不可变对象:Number ,String , Tuple,bool
可变对象: List , Set , Dictionary是可以改变内部的元素

 这里复制参考博客中的几个例子:

先看例子:

  1.  
def changestr (str):
    str = "inside"
    print "这是function中 , 值为:",str
mystr = "outside"
changestr(mystr)
print "这是函数外边 , 值为:",mystr

输出结果:

这是function中 , 值为: inside
这是函数外边 , 值为: outside

即 传入不可变对象字符串,在函数内对其操作不影响调用结束后字符串的值,即不发生改变。

ps: Number和Tuple结果是一样的,这三种类型只能通过重新赋值来改变对象的值 .

  1.  
def changestr (str):
    str.append(3)
    print "这是function中 , 值为:",str
mystr = [1,2]
changestr(mystr)
print "这是函数外边 , 值为:",mystr

结果:

这是function中 , 值为: [1, 2, 3]
这是函数外边 , 值为: [1, 2, 3]
  • 对于可变对象,在函数体中的修改 , 对对象本身的值发生了改变 , 在函数之外 , 该列表的内容依然发生了改变 , 这是事先就能猜测到的结果 , 因为python中的参数 , 传入的是变量引用的副本 , 它与变量指向同一个值.

3


def change2(list):
    list = [1,2,3,4]
mylist = ["aa",21]
print(mylist)
change2(mylist)
print(mylist)

输出结果:


['aa', 21]
['aa', 21]

可变对象在函数体中的重新赋值 , 没有对外部变量的值产生影响 , 不过仔细一想 , 却又在情理之中 .

  • 即变量中存储的是引用 , 是指向真正内容的内存地址(当然 ,java中的八大基本数据类型 , 变量名和值都是存储在堆栈中的 ) , 对变量重新赋值 , 相当于修改了变量副本存储的内存地址 , 而这时的变量已经和函数体外的变量不是同一个了, 在函数体之外的变量 , 依旧存储的是原本的内存地址 , 其值自然没有发生改变 .

3

def change2(list):
    list1 =list
    list1.append(34)
mylist = ["aa",21]
print mylist
change2(mylist)
print mylist

输出结果:


['aa', 21]
['aa', 21, 34]
  • 函数体传入的参数 , 为函数体外变量引用的副本 .
  • 在函数体中改变变量指向的堆中的值 , 对函数外变量有效.
  • 在函数体中改变变量的引用 , 对函数外变量无效

 总结:

根据上述几个例子,可以看出python中的不可变对象传值相当于C语言中的值传递,函数体内的改变不会改变函数体外的值。

可变对象传值相当于C语言中的指针传递,函数体内的改变会改变函数体外的值。如果python中函数体内有一个变量和函数体的参数名一样,这时候也不会改变,毕竟传入的参数和函数体内的变量的地址不一样。

解决方法

temp1 = copy.deepcopy(temp)

这样就可以深度复制temp中的值到temp1中了,这样可变对象传入的时候,函数体内的改变就不会影响函数体外了。

猜你喜欢

转载自blog.csdn.net/qq_23418043/article/details/82285878
今日推荐