python函数引用传参 python函数参数引用传递

python中值传递还是引用传递?首先,Python中一切事物皆对象 , 变量是对对象在内存中的存储和地址的抽象 。所有的变量都可以理解是内存中一个对象的“引用”,或者 , 也可以看似c中void*的感觉 。
python中统一都是引用传递 , 同时要注意类型是属于对象的,而不是变量 。而对象有两种,“可更改”(mutable)与“不可更改”(immutable)对象 。在python中,strings, tuples, 和numbers是不可更改的对象,而list,dict等则是可以修改的对象 。
当我们写下面语句时:
Python解释器其实顺序干了两件事情:
从这里可以看出strings类型是不可变量 , 不可变实际上指的是不会更该字符串,比如把a = '123' 变为 a ='1234' 实际上是先创建了 “1234” 再用a去指向它 。
但是 , 像list,dict等“可更改”的变量,他们会直接再本地更改 , 不会进行副本拷贝 。
简言之,当在 Python 中 a = sth 应该理解为给 sth 贴上了一个标签 a 。当再赋值给 a 的时候 , 就好象把 a 这个标签从原来的 sth 上拿下来 , 贴到其他对象上,建立新的"引用" 。
既然Python只允许引用传递 , 那有没有办法可以让两个变量不再指向同一内存地址呢?
copy对于一个复杂对象的子对象并不会完全复制,什么是复杂对象的子对象呢?就比如序列里的嵌套序列,字典里的嵌套序列等都是复杂对象的子对象 。对于子对象,python会把它当作一个公共镜像存储起来 , 所有对他的复制都被当成一个引用,所以说当其中一个引用将镜像改变了之后另一个引用使用镜像的时候镜像已经被改变了 。
deepcopy的时候会将复杂对象的每一层复制一个单独的个体出来 。当然其中主要的操作还是地址问题 。
当一个引用传递给函数的时候,函数自动复制一份引用,这个函数里的引用和外边的引用没有半毛关系了.所以第一个例子里函数把引用指向了一个不可变对象,当函数返回的时候,外面的引用没半毛感觉.而第二个例子就不一样了,函数内的引用指向的是可变对象,对它的操作就和定位了指针地址一样,在内存里进行修改.
引用计数
PyObject是每个对象必有的内容 , 其中ob_refcnt就是做为引用计数 。当一个对象有新的引用时,它的ob_refcnt就会增加,当引用它的对象被删除,它的ob_refcnt就会减少.引用计数为0时,该对象生命就结束了 。
优点:
缺点:
python 函数参数类型 python 的函数参数类型分为4种:
1.位置参数:调用函数时根据函数定义的参数位置来传递参数,位置参数也可以叫做必要参数,函数调用时必须要传的参数 。
当参数满足函数必要参数传参的条件,函数能够正常执行:
add(1,2)#两个参数的顺序必须一一对应,且少一个参数都不可以
当我们运行上面的程序,输出:
当函数需要两个必要参数,但是调用函数只给了一个参数时,程序会抛出异常
add(1)
当我们运行上面的程序,输出:
当函数需要两个必要参数,但是调用函数只给了三个参数时 , 程序会抛出异常
add(1,2,3)
当我们运行上面的程序,输出
2.关键字参数:用于函数调用 , 通过“键-值”形式加以指定 。可以让函数更加清晰、容易使用 , 同时也清除了参数的顺序需求 。
add(1,2) # 这种方式传参,必须按顺序传参:x对应1,y对应:2
add(y=2,x=1) #以关健字方式传入参数(可以不按顺序)
正确的调用方式
add(x=1, y=2)
add(y=2, x=1)
add(1, y=2)

推荐阅读