
正文
python函数传引用 python引用传递和值传递
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
python 引用
python引用有哪些?来和我一起解读一下吧~
python不允许程序员用传值和传引用,可以选择选用“传对象引用”的方式,这种方式等同于将传值和传引用综合起来,如果函数收到的是一个可变对象的引用,就能修改对象的原始值,相当于通过“传引用”来传递对象,如果函数收到的是一个不可变对象的引用,就不能直接修改原始对象,相当于通过“传值’来传递对象。
python引用主要有:不可变数据引用和可变数据引用,其中不可变数据引用包括:字符串String、浮点型Float、元祖Tuple。
1、字符串String
#1.字符串引用 a='1234' b=a a='hello' print('a:',a) #a:hello print('b:',b) #b:1234 #查看内存地址 print('a的内存地址是:',id(a)) print('a的内存地址是:',id(b)) 结果是: a: hellob: 1234a的内存地址是: 1651738050720a的内存地址是: 1651737219456 分析:b的值指向a的值。python开辟了新的内存空间给b,所以a和b的内存地址不一样。
2、浮点型Float
#2.浮点型引用 x=3.14 y=x x=9.88 print('x:',x) print('y:',y) print('x的内存地址是:',id(x)) print('y的内存地址是:',id(y)) 结果是: x: 9.88y: 3.14x的内存地址是: 2578075558248y的内存地址是: 2578075558008
3、元祖Tuple
元祖虽然是序列,且包含多个元素,但是不支持原处修改,如tuple[1]=1是非法的。#3.元祖引用 t1=(1,2,3,4,5) t2=t1 t1=('tuple','hello') print('t1:',t1) print('t2:',t2) print('t1的内存地址是:',id(t1)) print('t2的内存地址是:',id(t2)) 结果是: t修改后为: (1, 2, 3, ['x', 'a', 'D', 'b']) 可变数据引用包括:列表引用、字典引用、函数的传递引用
1、列表引用
#4 列表的可变引用 list1=[1,2,3,4,5] list2=list1 list1[3]='list' print('list1=====%s'%list1) print('list2=====%s'%list2) print('list1的内存地址是:',id(list1)) print('list2的内存地址是:',id(list2)) 结果是: list1=====[1, 2, 3, 'list', 5]list2=====[1, 2, 3, 'list', 5]list1的内存地址是: 2769992249864list2的内存地址是: 2769992249864
2、函数的传递引用
def eggs(someParameter): someParameter.append('hello list') spam=[1,2,3,4] eggs(spam) print(spam) 结果是: [1, 2, 3, 4, 'hello list']
3、字典引用 #5 字典的引用 a={'name':'Cathy','age':'27','job':'coder'} b=a a['age']='30' b['name']='Bob' print('a======%s'%a) print('b======%s'%b) print('a的内存地址是:', id(a)) print('b的内存地址是:', id(b)) 结果是: a======{'name': 'Bob', 'age': '30', 'job': 'coder'} b======{'name': 'Bob', 'age': '30', 'job': 'coder'} a的内存地址是: 2510825602792 b的内存地址是: 2510825602792
相关问答
Q1: python中变量的引用、可变和不可变类型、局部变量和全局变量
变量的引用
变量和数据都是保存在内存中的
变量和数据是分开存储的
数据保存在内存中某个位置python函数传引用,通过地址来标记
变量保存的是数据的地址,通过地址可以找到数据在内存空间的位置
把变量保存数据地址的过程称为引用
变量的重新赋值修改的是变量中引用数据的内存地址
变量之间的赋值实际是引用的传递
函数参数的传递,本质也是引用的传递
函数的返回值本身也是引用的传递
可变和不可变类型
不可变类型,内存中的数据不允许被修改python函数传引用:数字类型(int,bool,float,complex,long(2,x)、字符串、元组(tuple)
可变类型,内存中的数据可以被修改:列表list、字典dict
无论是可变还是不可变数据类型,通过赋值语句,都会改变变量的引用
Hash函数只能接收不可变数据类型,字典的键也只能是不可变数据类型,字典的value值可以是任意数据类型
局部变量
1.在函数内部定义的变量就是局部变量(作用范围只能是当前函数内部)
2.在函数外部无法直接访问局部变量
3.不同的函数中可以定义同名的局部变量
4.局部变量的生命周期:从定义变量时开始,到函数运行结束
全局变量
1.在所有函数外边定义的变量就是全局变量
2.让所有函数都能访问到,可以作为函数通信的桥梁
3.一般情况下,为了和普通变量的区别,需要加上g_或gl_前缀
4.全局变量一般放在所有函数的最上面
5.在函数内部修改全局变量,必须要加上global关键字,如果不加global只是定义了一个同名的局部变量
函数的多个返回值
Q2: python中视图函数传值的数据类型可以传对象吗
python的一切数据类型都是对象。但是python的对象分为不可变对象和可变对象。python的变量是引用python函数传引用,对python变量的赋值是引用去绑定该对象。
可变对象的数据发生改变,例如列表和字典,引用不会更改绑定对象,毕竟本身就是用于增删改查的,频繁地产生新对象必然导致开销巨大,只需要该对象内部变化就行python函数传引用;但对于绑定了不可变对象的引用,对象一旦改变就会使引用绑定新的对象。
这一点也会反应到函数的参数上。python的传值方式是“传对象”引用。python的函数,形参实际上是引用,实参便是对象绑定到该引用上。本质是形参会被作为函数的局部变量,在开辟的函数的栈内存中被声明。
简要来讲:
如果参数是数,则类似值传递,
如果参数是列表和字典,则类似引用传递。
每个对象都会有个id, 可以用id()验证以上说法:
这个函数的参数是列表,是可变对象。
Q3: 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时,该对象生命就结束了。
优点:
缺点:
Q4: python函数传对象对性能的影响
python函数传对象对性能有影响。在Python中,一切皆对象,Python参数传递采用的都是“传对象引用”的方式。实际上,这种方式相当于传值和传引用的一种综合。如果函数收到的是一个可变对象(比如字典或者列表)的引用,就能修改对象的原始值,相当于通过“传引用”来传递对象。如果函数收到的是一个不可变对象(比如数字、字符或者元组)的引用,就不能直接修改原始对象,相当于通过“传值’来传递对象,此时如果想改变这些变量的值,可以将这些变量申明为全局变量。
Q5: python函数调用的参数传递
pythonpython函数传引用的函数参数传递是"引用传递(地址传递)"。
python中赋值语句python函数传引用的过程(x = 1):先申请一段内存分配给一个整型对象来存储数据1python函数传引用,然后让变量x去指向这个对象python函数传引用,实际上就是指向这段内存(这里有点和C语言中的指针类似)。
在Python中python函数传引用,会为每个层次生成一个符号表,里层能调用外层中的变量,而外层不能调用里层中的变量,并且当外层和里层有同名变量时,外层变量会被里层变量屏蔽掉。函数 调用 会为函数局部变量生成一个新的符号表。
局部变量:作用于该函数内部,一旦函数执行完成,该变量就被回收。
全局变量:它是在函数外部定义的,作用域是整个文件。全局变量可以直接在函数里面应用,但是如果要在函数内部改变全局变量,必须使用global关键字进行声明。
注意 :默认值在函数 定义 作用域被解析
在定义函数时,就已经执行力它的局部变量
python中不可变类型是共享内存地址的:把相同的两个不可变类型数据赋给两个不同变量a,b,a,b在内存中的地址是一样的。
关于python函数传引用和python引用传递和值传递的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。







