python对象的复制问题,按值传递?引用传递?
这部分这篇博文说的很明白,转了过来
作者:winterTTr (转载请注明)http://blog.csdn.net/winterttr/article/details/2590741#0-tsina-1-71597-397232819ff9a47a7b7e80a40613cfe1
我想,这个标题或许是很多初学者的问题。尤其是像我这样的对C/C++比较熟悉,刚刚进入python殿堂的朋友们
。C/C++的函数参数的传递方式根深蒂固的影响这我们的思维--引用?传值?究竟是那种呢。
呵呵,语言的特性决定了是使用的方法,那么,现在我们来探究一下python的函数参数传递方式。
在开始之前,我们有必要分清一下python的一些基础概念。
首先要说的是:变量 与 对象
在python中,类型属于对象,变量是没有类型的,这正是python的语言特性,也是吸引着很多pythoner的一点。所有的变量都可以理解是内存中一个对象的“引用”,或者,也可以看似c中void*的感觉。所以,希望大家在看到一个python变量的时候,把变量和真正的内存对象分开。
类型是属于对象的,而不是变量。这样,很多问题就容易思考了。
例如:
nfoo = 1 #一个指向int数据类型的nfoo(再次提醒,nfoo没有类型)
lstFoo = [1] #一个指向list类型的lstFoo,这个list中包含一个整数1。
对应于上一个概念,就必须引出另了另一概念,这就是“可更改”(mutable)与“不可更改”(immutable)对象。
对于python比较熟悉的人们都应该了解这个事实,在python中,strings, tuples, 和numbers是不可更改的对象,而list,dict等则是可以修改的对象。那么,这些所谓的可改变和不可改变影响着什么呢?
还是上面的例子:
nfoo = 2
这时,内存中原始的1对象因为不能改变,于是被“抛弃”,另nfoo指向一个新的int对象,其值为2
lstFoo[0] = 2
更改list中第一个元素的值,因为list是可改变的,所以,第一个元素变更为2,其实应该说有一个新int对象被指定给lstFoo 所指向的对象的第一个值,但是对于lstFoo 来说,所指向的对象,并没有变化,就是这个看似void*的变量所指向的对象仍旧是刚刚的那个有一个int对象的list。(听着有点晕吧,仔细琢磨一下就明白了,嘿)
好了,被我这么填鸭似的复习了一下python的基础知识,改转回题目的问题了,Python的函数参数传递:传值?引用?
对于变量(与对象相对的概念),其实,python函数参数传递可以理解为就是变量传值操作(注意哦,我说的是变量,不是对象 =_= )
接着说例子好了:
def ChangeInt( a ):
a = 10 # change the number
nfoo = 2
ChangeInt(nfoo)
print nfoo #结果是2
这时发生了什么,有一个int对象2,和指向它的变量nfoo,当传递给ChangeInt的时候,按照传值的方式,复制了变量nfoo的值,这样,a就是nfoo指向同一个Int对象了,函数中a=10的时候,发生什么?
(还记得我上面讲到的那些概念么),int是不能更改的对象,于是,做了一个新的int对象,另a指向它(但是此时,被变量nfoo指向的对象,没有发生变化),于是在外面的感觉就是函数没有改变nfoo的值,看起来像C++中的传值方式。
def ChangeList( a ):
a[0] = 10 # change the number
lstFoo = [2]
ChangeList(lstFoo )
print nfoo #结果是[10]
当传递给ChangeList的时候,变量仍旧按照“传值”的方式,复制了变量lstFoo 的值,于是a和lstFoo 指向同一个对象,但是,list是可以改变的对象,对a[0]的操作,就是对lstFoo指向的对象的内容的操作,于是,这时的a[0] = 10,就是更改了lstFoo 指向的对象的第一个元素,所以,再次输出lstFoo 时,显示[10],内容被改变了,看起来,像C++中的按引用传递。
补充一下复制问题,是复制,给可变变量另建一个指向的对象:
list 的拷贝问题:
>>> a
[1, 2]
>>> b=a[:]
>>> b
[1, 2]
>>> b[0]=20
>>> b
[20, 2]
>>> a
[1, 2]
2,
import copy
>>> c=copy.copy(a)
>>> c
[1, 2]
>>> c[1]=30
>>> c
[1, 30]
>>> a
[1, 2]
>>> b
[20, 2]
dictionary:
1 >>> a=[('he',1),('wo','jia')]
2 >>> p=dict(a)
3 >>> p
4 {'wo': 'jia', 'he': 1}
5 >>> b=p.copy()
6 >>> b
7 {'wo': 'jia', 'he': 1}
8 >>> b['wo']='ja'
9 >>> b
10 {'wo': 'ja', 'he': 1}
11 >>> p
12 {'wo': 'jia', 'he': 1}
python对象的复制问题,按值传递?引用传递?的更多相关文章
- 验证python中函数传参是引用传递
定义: 值传递(pass by value)是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数. 引用传递(pass by reference)是指在 ...
- python对象的复制问题
list 的拷贝问题: 1, >>> a [1, 2] >>> b=a[:] >>> b [1, 2] >>> b[0]=20 ...
- java面试题:当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?
答:是值传递.Java编程语言只有值传递参数. 当一个对象实例作为一个参数被传递到方法中时,参数的值就是该对象的引用一个副本.指向同一个对象,对象的内容可以在被调用的方法中改变,但对象的引用(不是引用 ...
- c/c++值传递和引用传递
今天看数据结构的时候,因为是c语言版的,刚开始学的时候就对指针搞的焦头烂额,今天,发现参数传递的时候,&符号也莫名其妙,搜了一篇好文,转载下来. 一. 函数参数传递机制的基本理论 函数参数传递 ...
- Java 到底是值传递还是引用传递?
关于这个问题,引发过很多广泛的讨论,看来很多程序员对于这个问题的理解都不尽相同,甚至很多人理解的是错误的.还有的人可能知道Java中的参数传递是值传递,但是说不出来为什么. 在开始深入讲解之前,有必要 ...
- python-socket.error[10054]:对象的复制
1.socket.error[10054],对方强制关闭了连接 在用socket.recvfrom时,若事先没有bind时, 先使用socket.sendto,socket.recvfrom 有时会出 ...
- Java千百问_05面向对象(011)_引用传递和值传递有什么差别
点击进入_很多其它_Java千百问 1.什么是值传递 值传递,是将内存空间中某个存储单元中存放的值,传送给还有一个存储单元.(java中的存储单元并不是物理内存的地址,但具有相关性) 比如: //定义 ...
- 【Java思考】Java 中的实参与形参之间的传递到底是值传递还是引用传递呢?
科普: 值传递(pass by value)是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数. 引用传递(pass by reference)是指在 ...
- python函数参数是值传递还是引用传递(以及变量间复制后是否保持一致):取决于对象内容可变不可变
函数参数传递本质上和变量整体复制一样,只是两个变量分别为形参a和实参b.那么,a=b后,a变了,b值是否跟着变呢?这取决于对象内容可变不可变 首先解释一下,什么是python对象的内容可变不可变? p ...
随机推荐
- I Like for You to Be Still【我会一直喜欢你】
I Like for You to Be Still I like for you to be still 我会一直喜欢这你 It is as though you are absent 就算你并不在 ...
- 分数调查 HihoCoder - 1515
小Hi的学校总共有N名学生,编号1-N.学校刚刚进行了一场全校的古诗文水平测验. 学校没有公布测验的成绩,所以小Hi只能得到一些小道消息,例如X号同学的分数比Y号同学的分数高S分. 小Hi想知道利用这 ...
- 电脑卡,eclipse Android stadio 卡,什么都卡解决方法
昨天还好好的,今天什么都没有动就很卡.Android stadio 半天,改了东西才编译.什么都慢一拍,你能感觉到,打开网页也好,什么也好. 莫名的问题,总是被莫名的解决.真的,下了个360杀毒,没效 ...
- windows下,cmd 运行 python 脚本,选中文字就停止运行了【已解决】
参考资料: https://jingyan.baidu.com/article/ce09321bb95dda2bff858f26.html 问题原因: cmd 里面,快速编辑模式会暂停程序 解决步骤: ...
- Python-S9-Day126——Scrapy爬虫框架
01 今日内容概要 02 内容回顾和补充:scrapy 03 内容回顾和补充:网络和并发编程 04 Scrapy爬虫框架:pipeline做持久化(一) 05 Scrapy爬虫框架:pipeline做 ...
- c语言入门-02-第一个c程序开始
我们来开我们第一个c代码 #include<stdio.h> int main(){ // print num int num; num = 1; printf("%d\n&qu ...
- Leetcode 605.种花问题
种花问题 假设你有一个很长的花坛,一部分地块种植了花,另一部分却没有.可是,花卉不能种植在相邻的地块上,它们会争夺水源,两者都会死去. 给定一个花坛(表示为一个数组包含0和1,其中0表示没种植花,1表 ...
- 基于单层决策树的AdaBoost算法源码
基于单层决策树的AdaBoost算法源码 Mian.py # -*- coding: utf-8 -*- # coding: UTF-8 import numpy as np from AdaBoos ...
- 菜鸟之路——机器学习之非线性回归个人理解及python实现
关键词: 梯度下降:就是让数据顺着梯度最大的方向,也就是函数导数最大的放下下降,使其快速的接近结果. Cost函数等公式太长,不在这打了.网上多得是. 这个非线性回归说白了就是缩小版的神经网络. py ...
- Unity 移动方式总结
1. 简介 在Unity3D中,有多种方式可以改变物体的坐标,实现移动的目的,其本质是每帧修改物体的position. 2. 通过Transform组件移动物体 Transform 组件用于描述物体在 ...