精华内容
下载资源
问答
  • Python传值还是传引用

    千次阅读 2019-04-19 15:09:38
    Python传值还是传引用 1、Python可变对象与不可变对象 不可变对象:该对象所指向的内存中的值不能被改变。当改变某个变量时候,由于其所指的值不能被改变,相当于把原来的值复制一份后再改变,这会开辟一个新的地址...

    Python传值还是传引用

    1、Python可变对象与不可变对象

    不可变对象:该对象所指向的内存中的值不能被改变。当改变某个变量时候,由于其所指的值不能被改变,相当于把原来的值复制一份后再改变,这会开辟一个新的地址,变量再指向这个新的地址。
    数值类型(int和float)、字符串str元组tuple都是不可变类型。

    可变对象:该对象所指向的内存中的值可以被改变。变量(准确的说是引用)改变后,实际上是其所指的值直接发生改变,并没有发生复制行为,也没有开辟新的出地址,通俗点说就是原地改变。
    列表list字典dict集合set是可变类型,等!(除了少数不可变对象)

    2、内存示例

    首先需要明确的是,Python中一切事物皆对象,变量是对对象在内存中的存储和地址的抽象。
    在这里插入图片描述
    “=”(赋值号)是将右侧对象的内存地址赋值给左侧的变量。

    以下例子详细说明:
    a = "abc"
    

    Python解释器顺序干了两件事情:
    1、在内存中创建一个字符串“abc”;
    2、在内存中创建一个名为“a”的变量,并将“a”指向字符串“abc”(将“abc”的地址保存到“a”中)。
    这样我们就能通过操作“a”而改变内存中的“abc”。

    a = "123"
    b = a
    a = "xyz"
    

    执行第一句Python解释器创建字符串“123”和变量“a”,并把“a”指向“123”。
    在这里插入图片描述
    执行第二句,因为“a”已经存在,并不会创建新的对象,但会创建变量“b”,并把“b”指向“a”指向的字符串“123“。
    在这里插入图片描述
    执行第三句,首先会创建字符串“xyz”,然后把“xyz”的地址赋予“a“(“a”指向字符串“xyz”)。
    在这里插入图片描述
    我们可以通过调用id()方法查看变量所指向对象在内存中的地址。

    3、值传递还是引用传递

    Python参数传递统一使用的是引用传递方式。因为Python对象分为可变对象(list,dict,set等)和不可变对象(number,string,tuple等),当传递的参数是可变对象的引用时,因为可变对象的值可以修改,因此可以通过修改参数值而修改原对象,这类似于C语言中的引用传递;当传递的参数是不可变对象的引用时,虽然传递的是引用,参数变量和原变量都指向同一内存地址,但是不可变对象无法修改,只能复制一份,所以参数的重新赋值不会影响原对象,这类似于C语言中的值传递。

    4、浅拷贝(copy)和深拷贝(deepcopy)

    既然Python只允许引用传递,那有没有办法可以让两个变量不再指向同一内存地址呢?
    Python提供了一个copy模块,帮助我们完成这件事。

    1、不使用copy模块

    在这里插入图片描述
    可以发现变量“a”,“b”指向同一块内存区域,所以对其中一个的操作将会影响到另一个。

    2、使用copy模块

    在这里插入图片描述
    变量“e”和“f”是通过copy方式创建的,可以看见他们的id互不相同,并且与“c”不同,说明采用copy方式会将对象拷贝一份到新的内存地址中。
    但copy和deepcopy有什么区别呢?

    3、接着往下实验

    在这里插入图片描述
    从红色框出来处可以看见,虽然使用copy()方法,变量“i”指向的内存和“g”不再相同,但是“i”和“g”第二层列表还是同一个地址。但是deepcopy()方法第二层列表的地址也和“g”不同了。
    所以我们说,copy()是浅拷贝,不管对象多么复杂,都只拷贝第一层。
    在这里插入图片描述
    deepcopy()是深拷贝,完全复制原变量的所有层的所有数据,在内存中生成一套完全相同的内容。
    在这里插入图片描述

    展开全文
  • 面试遇到一个问题:如何删除...即Python不允许程序员选择采用传值或传引用Python参数传递采用的是“对象引用”的方式。实际上,这种方式相当于传值和传引用的一种综合。如果函数参数收到的是一个可变对象(比如...

    面试遇到一个问题:如何删除一个python对象?

    下面将介绍python的对象引用和 del删除引用

    1.  首先介绍下python的对象引用

    1)Python中不存在传值调用,一切传递的都是对象引用,也可以认为是传址调用。即Python不允许程序员选择采用传值或传引用。Python参数传递采用的是“传对象引用”的方式。实际上,这种方式相当于传值和传引用的一种综合。如果函数参数收到的是一个可变对象(比如字典或者列表)的引用,就能修改对象的原始值——相当于通过“传引用”来传递对象。如果函数收到的是一个不可变对象(比如数字、字符或者元组)的引用,就不能直接修改原始对象——相当于通过"传值"来传递对象。
    2)当复制列表或字典时,就复制了对象列表的引用,如果改变引用的值,则修改了原始的参数。

    3)为了简化内存管理,Python通过引用计数机制实现自动垃圾回收功能,Python中的每个对象都有一个引用计数,用来计数该对象在不同场所分别被引用了多少次。每当引用一次Python对象,相应的引用计数就增1,每当消毁一次Python对象,则相应的引用就减1,只有当引用计数为零时,才真正从内存中删除Python对象。

    2. 可变对象与不可变对象的概念与分类

    Python在heap中分配的对象分成2类:

         不可变对象(immutable object):Number(int、float、bool、complex)、String、Tuple. 采用等效于“传引用”的方式。

         可变对象(mutable object):List、dictionary.采用等效于“传值”的方式。

    Python的数据类型和c不太一样,有一种分类标准,可变(mutable)/不可变(immutable).

    我理解的可变,就是在内存中的那块内容(value)是否可以被改变。如果是不可变的,在对对象本身操作的时候,必须在内存的另外地方再申请一块区域(因为老区域#不可变#),老的区域就丢弃了(如果还有其他ref,则ref数字减1,类似unix下的hard-link)。如果是可变的,对对象操作的时候,不需要再在其他地方申请内存,只需要在此对象后面连续申请(+/-)即可,也就是它的address会保持不变,但区域会变长或者变短。

    list1 = [1, 2, 3]
    list2 = list1
    list3 = list1
    print('list1=', list1, '\nlist2=', list2, '\nlist3=', list3)
    print('id(list1)=', id(list1), '\nid(list2)=', id(list2), '\nid(list3)=', id(list3))
    list1= [1, 2, 3] 
    list2= [1, 2, 3] 
    list3= [1, 2, 3]
    id(list1)= 2604378467016 
    id(list2)= 2604378467016 
    id(list3)= 2604378467016

    一开始list1,list2,list3的取值和id都相同

    list2 = list2 + [4]      # 不可变类型操作
    print('list1=', list1, '\nlist2=', list2, '\nlist3=', list3)
    print('id(list1)=', id(list1), '\nid(list2)=', id(list2), '\nid(list3)=', id(list3))
    list1= [1, 2, 3] 
    list2= [1, 2, 3, 4] 
    list3= [1, 2, 3]
    id(list1)= 2604378467016 
    id(list2)= 2604378402376 
    id(list3)= 2604378467016

    进行操作 list2 = list + [4] 这个不可变类型操作后,list1和list3没有受到影响,list2的值和id都发生变化。

    list2 += [4]      # 可变类型操作
    print('list1=', list1, '\nlist2=', list2, '\nlist3=', list3)
    print('id(list1)=', id(list1), '\nid(list2)=', id(list2), '\nid(list3)=', id(list3))
    list1= [1, 2, 3] 
    list2= [1, 2, 3, 4, 4] 
    list3= [1, 2, 3]
    id(list1)= 2604378467016 
    id(list2)= 2604378402376 
    id(list3)= 2604378467016

    进行操作list2 += [4] 这个可变类型操作后,list2的内容和id均发生变化

    list3.append(5)         # 可变类型操作
    print('list1=', list1, '\nlist2=', list2, '\nlist3=', list3)
    print('id(list1)=', id(list1), '\nid(list2)=', id(list2), '\nid(list3)=', id(list3))
    list1= [1, 2, 3, 5] 
    list2= [1, 2, 3, 4, 4] 
    list3= [1, 2, 3, 5]
    id(list1)= 2604378467016 
    id(list2)= 2604378402376 
    id(list3)= 2604378467016

    列表append()操作是可变类型操作,执行list3.append(5)之后,list1和list3指向的列表元素发生变化,但是id不变。

     3. del 是删除引用而不是删除对象,对象由自动垃圾回收机制(GC)删除,当某个对象的所有引用都被删除后,会自动执行魔法方法__del__来清除此垃圾。


    可以看到x和y指向同一个列表,但是删除x后,y并没有受到影响。这是为什么呢?
    The reason for this is that you only delete the name,not the list itself,In fact ,there is no way to delete values in python(and you don’t really need to because the python interpreter does it by itself whenever you don’t use the value anymore)
     举个例子,一个数据(比如例子中的列表),就是一个盒子,我们把它赋给一个变量x,就是好像把一个标签x贴到了盒子上,然后又贴上了y,用它们来代表这个数据,但是用del删除这个变量x就像是把标有x的标签给撕了,剩下了y的标签。

    再看一个例子:


    # 本文转自 https://www.cnblogs.com/ant-colonies/p/6602742.html

    展开全文
  • python函数传参是传值还是传引用? https://www.cnblogs.com/loleina/p/5276918.html 结论:python不允许程序员选择采用传值还是传引用Python参数传递采用的肯定是“对象引用”的方式。这种方式相当于传值和...

    python函数传参是传值还是传引用? https://www.cnblogs.com/loleina/p/5276918.html

    结论:python不允许程序员选择采用传值还是传引用。Python参数传递采用的肯定是“传对象引用”的方式。这种方式相当于传值和传引用的一种综合。如果函数收到的是一个可变对象(比如字典或者列表)的引用,就能修改对象的原始值--相当于通过“传引用”来传递对象。如果函数收到的是一个不可变对象(比如数字、字符或者元组)的引用,就不能直接修改原始对象--相当于通过“传值’来传递对象。

    展开全文
  • Python变量引用浅析

    千次阅读 2019-04-09 11:02:30
    对于刚接触Python语言的同学来说,可能不太了解Python中参数赋值的机制:在Python中,对一个变量的赋值,实际上是修改了数据的引用。 本文将在下面举几个例子来帮助说明该机制 首先我们来证明一下,对于变量的赋值...

    引言:
    对于刚接触Python语言的同学来说,可能不太了解Python中参数赋值的机制:在Python中,对一个变量的赋值,实际上是修改了数据的引用。 本文将在下面举几个例子来帮助说明该机制


    首先我们来证明一下,对于变量的赋值实际上是修改了数据的引用这个描述:


    从ipython的运行结果中,我们可以看出,当给一个变量赋值时,其实对于该变量a而言,只是一个标签(数据的引用),类似于下图

    而将以赋值的变量a赋给另一个新变量b时,实际上,对于该新变量b而言,依然是该以赋值变量a所对应的常量10的一个标签,类似于下图

    所以当我们修改a的值,并不会修改b的引用,只是简单地把a修改为了新值20的引用,此时对应的图示为


    函数参数的传递:
    结论:对于Python中函数参数的传递,这一点有别于其他语言,他传递的是实参所对应的引用而不是实参所对应的值。
    我们用一个测试程序来帮助说明:
    [Note:python中的id函数返回的结果是该参数对应的内存地址]

    def printID(para):
    	print("Input para's id is {}".format(id(para)))
    
    para = 10
    print("10's id is {}".format(id(para)))
    printID(para)
    
    -------------------------
    输出结果:
    10's id is 1746174320
    Input para's id is 1746174320
    

    由此可见,在传递参数时,确实传递的是引用。

    函数返回值的传递:
    结论:函数在传递返回值时,也是传递该参数对应数据的引用。
    我们用一个测试程序来帮助说明:

    def printID():
    	r = 2
    	print("2's id = {}".format(id(2)))
    	return r
    
    r = printID()
    print("r's id = {}".format(id(r)))
    
    ---------------------------------
    输出结果:
    2's id = 1746174064
    r's id = 1746174064
    

    由此可见,函数在传递返回值确实传递也是该参数对应数据的引用。

    函数内部参数值的修改:
    结论:函数中若对传入的参数进行修改,只会在函数中生效,而无法改变传入的实参值:
    我们用一个测试程序来帮助说明:

    def test(num):
    	num = 10
    	print("function's num = {}".format(num))
    
    gl_num = 1
    test(gl_num)
    print("num = {}".format(gl_num))
    
    ----------------------------------
    输出结果:
    function's num = 10
    gl_num = 1
    

    为了方便大家更好地理解,我将用下图说明:


    再未执行函数中num = 10这一语句时,两个"标签":num和gl_num的引用图示为红线,当执行num = 10后,num就指向了10对应的内存地址,而gl_num指向的地址依旧不变。此外,这也能从另一方面说明,函数中传递的参数与实参并不是同一个"标签",只是对于某一个地址的两个不同的"标签"。


    如果觉得我有地方讲的不好的或者有错误的欢迎给我留言,谢谢大家阅读(点个赞我可是会很开心的哦)~

    展开全文
  • python实现引用参数

    千次阅读 2019-05-12 10:54:38
    python没有C++中的指针和引用这些概念,直接传入变量不能实现类似引用参数的功能。 def incr_num(num): num += 1 num = 0 num 0 incr_num(num) num 0 这是因为: 2. python中的整数都有其固定id >>...
  • Python引用计数器

    千次阅读 2013-07-24 11:12:07
     包保持追中内存中的对象,Python使用了引用计数器这个简单的技术。也就是说Python内部记录着所有使用中的对象有多少引用。一个内部跟踪变量,称为一个引用计数器。当对象被创建时,就创建了一个引用计数,当这个...
  • python——引用

    千次阅读 多人点赞 2019-05-05 13:12:22
    今悟引用,遂做笔记,以供大观~ spam = 45 cheese = spam spam = 100 print(spam) print(cheese) 在运行时,该程序输出如下: 100 45 你将42赋值给spam变量,然后拷贝spam的值,将它赋值给变量cheese,当稍后将...
  • Python对象引用和del删除引用

    万次阅读 2014-11-24 15:40:38
    为了简化内存管理,Python通过引用计数机制实现自动垃圾回收功能,Python中的每个对象都有一个引用计数,用来计数该对象在不同场所分别被引用了多少次。每当引用一次Python对象,相应的引用计数就增1,每当消毁一次...
  • Python函数参数传递:传值还是传引用

    万次阅读 多人点赞 2016-03-30 11:46:53
    引子首先来看一个列子:def change(val): val.append(100) ...按照C++语言的思维,如果Python函数参数的传递是传值的话,结果应该是[0, 1],如果是传引用的话,结果应该是[‘T’, ‘Z’, ‘Y’]。 可
  • python引用概念

    千次阅读 2019-04-27 22:35:32
    引用的概念 python中变量和数据是分开存储的 数据保存在内存中的一个位置 变量中保存数据在内存中的地址。变量中记录数据的地址,就叫做引用 使用id()函数可以查看变量中保存数据所在的内存地址 注意:如果变量已经...
  • python如何引用自定义模块?有什么注意事项啊,为什么使用import却告诉我语法错误?
  • Python3 引用HTMLTestRunner

    千次阅读 热门讨论 2019-01-08 12:42:14
    HTMLTestRunner 是 Python 标准库的 unittest 模块的一个扩展。它生成易于使用的 HTML 测试报告。 首先要下载 HTMLTestRunner.py 文件,下载地址:http://tungwaiyip.info/software/HTMLTestRu...
  • python 跨文件夹引用

    万次阅读 2016-08-15 14:45:33
    python 跨文件夹引用
  • python引用计数机制

    千次阅读 2018-11-06 20:17:26
    python内部使用引用计数,来保持追踪内存中的对象, Python内部记录了对象有多少个引用 ,即引用计数,当对象被创建时就创建了一个引用计数,当对象不再需要时,这个对象的引用计数为0时,它被垃圾回收。 总结一下...
  • Python引用自定义模块

    千次阅读 2017-02-19 20:42:02
    引用模块时,编译器会先在当前目录,接着去sys.path、Python的安装目录去寻找你引用的模块,如果没有的话,就会报错。 第一种情况,你的模块和你要使用的模块在同一目录下。Hello.py是一个模块,里面有一个...
  • Python FAQ1:传值,还是传引用

    千次阅读 2014-08-12 00:34:13
    由于思维定式,从C/C++转过来的Python初学者也经常会感到疑惑:在Python中,函数参数传递是传值,还是传引用呢? 看下面两段代码: 看完第一段代码,会有人说这是值传递,因为函数并没有改变x的值;看完第二段...
  • python获取引用对象的个数

    千次阅读 2019-03-19 18:27:05
    可以使用python中的sys模块的getrefcount()方法来获取对象引用的个数。 具体可以看以下的实例: import sys # 首先导入sys模块 class Dog: # 定义 Dog 类 pass dog = Dog() # 创建一个dog对象 print(sys....
  • File "C:\Users\wjw\AppData\Local\Programs\Python\Python35\lib\site-packages\sklearn\__init__.py", line 57, in from .base import clone File "C:\Users\wjw\AppData\Local\Programs\Python\Python35\lib\...
  • python 引用计数问题

    千次阅读 2019-04-21 15:25:35
    文章目录对象的引用计数+1的情况:对象被创建对象被引用...python的垃圾回收采用的是引用计数机制为主和分代回收机制为辅的结合机制,当对象的引用计数变为0时,对象将被销毁,除了解释器默认创建的对象外。(默认...
  • python 3.7引用docx操作word文档报错“docx.opc.exceptions.PackageNotFoundError: Package not found at.....”,网上搜的方法都尝试过了,没有用。python__docx-0.8.6-py2.py3-none-any.whl这个包已经没有了,下载...
  • 翻译:“json” 这个变量名没有被定义。 因为在调用api接口的时候使用了 json,就报错了。 解决办法: 直接导入就好了,Python 自带的不用安装。...Python引用提示:name 'json' is not defined. 问题解决办法
  • python引用的常用三种方法

    千次阅读 2019-08-23 14:31:43
    python引用 方法一 import<库名> <库名>.<函数名>(<函数参数>) 例如: import turtle turtle.setup(650,350,200,200) turtle.penup() turtle.pendown() turtle.fd(-250) 方法二 from<...
  • python中的引用

    万次阅读 2012-05-16 15:42:30
    1. python不允许程序员选择采用传值还是传引用Python参数传递采用的肯定是“对象引用”的方式。实际上,这种方式相当于传值和传引用的一种综合。如果函数收到的是一个可变对象(比如字典或者列表)的引用,就能...
  • python引用其他py文件里的函数方法Python中在脚本中引用其他文件函数的方法在导入文件的时候,Python只搜索当前脚本所在的目录,加载(entry-point)入口脚本运行目录和sys.path中包含的路径例如包的安装地址。...
  • Python的函数传值与传引用简解

    千次阅读 2013-11-25 16:18:16
    Python到底值传值还是传引用? 先看两段代码 代码1: 1 2 3 4 5 6 7 >>> a=3 >>> def f(b): ... b=1 ...  >>> f(a) >>> a 3 ...
  • c = [0] print(id(c)) #88878234568 def fun(c): c.append(1) #改变原始对象 print(c) #[0,1] print(id(c)) #88878234568 c.append(2) #改变原始对象 print(c) #[0, 1, 2] print(id(c)) #88878234568 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 318,953
精华内容 127,581
关键字:

python传引用

python 订阅