传值:被调函数局部变量改变不会影响主调函数局部变量

传址:被调函数局部变量改变会影响主调函数局部变量

Python参数传递方式:传递对象引用(传值和传址的混合方式),如果是数字,字符串,元组则传值;如果是列表,字典则传址;

1. Python中的传址和传值

Python是不允许程序员选择采用传值还是传址的。Python参数传递采用传值和传址的一种综合。

如果函数收到的是一个可变对象(比如字典或者列表),就能修改对象的原始值(相当于传址)。如果函数收到的是一个不可变对象(比如数字、字符或者元组)(其实也是对象地址),就不能直接修改原始对象——相当于传值。

所以python的传值和传址是根据传入参数的类型来选择的

传值的参数类型:数字,字符串,元组(immutable)

传址的参数类型:列表,字典(mutable)

def f1(a):
a += 1
def f2(a):
a.append([2, 5]) a = 1
b = [1, 2]
f1(a)
f2(b)
print(a) #实际输出:1
print(b) #实际输出:[1, 2, [2, 5]]

因为a是数字类型,是传值的方式,a的值不变,输出为1。b的类型是列表,是传址的形式,b的值会改变,输出:[1, 2, [2, 5]]

2. copy和deepcopy

Python中的对象之间赋值时是按引用传递的,如果需要拷贝对象,需要使用标准库中的copy模块。

(1). copy.copy 浅拷贝只拷贝父对象,不会拷贝对象内部的子对象(相当于只拷贝指向子对象的指针,不拷贝所指向的内容)。
(2). copy.deepcopy 深拷贝 拷贝对象及其子对象(拷贝子对象指针所指向的内容)

不止是函数里面,函数外面的引用也同样遵循这个规则:

a = 1
b = a
a = 2
print(a, b)  #实际输出:2, 1
a = [1]
b = a
a[0] = 2
print(a, b)  实际输出:[2][2]

在python中,当运行上面的代码时,如果a是字典或者列表,b=a操作并不是新建一个b变量在把a赋值给b,而是新建一个b变量,把b的值指向a,相当于c语言里面新建一个指向a的指针。所以当a的值发生改变时,b的值会相应改变。

但是,当我们想新建一个与a的值相等的b变量,同时b的值与a的值没有关联时,要怎么做?这时就用到copy与deepcopy了

import copy
a = [1, 2, 3]
b = a
a.append(4)
print(a, b) #实际输出:[1, 2, 3, 4] [1, 2, 3, 4] a = [1, 2, 3]
b = copy.copy(a)
a.append(4)
print(a, b) #实际输出:[1, 2, 3, 4] [1, 2, 3]

这里用了copy来让b与a相等,后面如果修改了a的值,b的值并不会改变。看来copy已经可以实现我们上面的提到的需求了,那么deepcopy又有什么用?

如果我们遇到这种情况,copy就解决不了了

a = [1, [1, 2], 3]
b = copy.copy(a)
a[1].append(4)
print(a, b) #实际输出:[1, [1, 2, 4], 3] [1, [1, 2, 4], 3]

当列表或字典参数里面的值是列表或字典时,copy并不会复制参数里面的列表或字典,这时就要用到deepcopy了

a = [1, [1, 2], 3]
b = copy.deepcopy(a)
a[1].append(4)
print(a, b) #实际输出:[1, [1, 2, 4], 3] [1, [1, 2], 3]

Python 传值和传址 copy/deepcopy的更多相关文章

  1. Python的传值和传址与copy和deepcopy

    1.传值和传址 传值就是传入一个参数的值,传址就是传入一个参数的地址,也就是内存的地址(相当于指针).他们的区别是如果函数里面对传入的参数重新赋值,函数外的全局变量是否相应改变,用传值传入的参数是不会 ...

  2. Java传值和传址

    调用函数时,传的参数过去可能是传值,也可能是传址.如果是传值,函数内部的操作对参数的值没有影响:如果是传址,函数内部的操作是对参数指向的内存进行操作,会影响参数的值. Java到底是传值还是传址?用下 ...

  3. javascript的变量,传值和传址,参数之间关系

    先把收获晾一下: 1.javascrip变量包含两种类型的值,一种为引用类型的值,一种是基本类型的值.引用类型包括:Array,Object,Function(可以这么理解,非基本类型的都是引用类型) ...

  4. 图解JS的传值与传址

    //编程过程中经常会碰到传值,传址的问题!今天的主题就是关于传值.与传址. //先讲讲赋值操作 //下例是原始类型赋值操作 var a=1,b=a,a=2; console.log("a=& ...

  5. JAVA传值与传址

    要了解JAVA中的传值与传址问题,必要先要了解JVA中的栈内存和堆内存,>>>>点些查看<<<<昨天写的学习记录 栈:基本数据类型.数据的引用变量,这两 ...

  6. javascript . 05 json的组成、for...in 遍历对象、简单数据类型与复杂数据类型的传值与传址、内置对象

    对象字面量  JSON var obj = { aaa :999}; var json={"aaa":999,"bbb":888}; "kay&quo ...

  7. 工控随笔_18_西门子_WinCC的VBS脚本_07_变量作用域和传值、传址

    在vbs脚本中也存在和其他编程语言一样的概念,那就是变量的作用域,变量的作用域决 定在什么范围内可以访问. 同样的在vbs脚本中对于变量也有一个生命周期, 变量的生命周期决定了变量的存续时间 这个主要 ...

  8. java方法中,传参是传值还是传址问题(对比C语言、C#和C++)

    问题引出: 编写一个简单的交换值的小程序,如果我们只是简单地定义一个交换函数接收两个数,在函数内部定义一个中间变量完成交换.那么当我们把a,b两个实参传给这个函数时,往往得不到预期的结果.这是为什么呢 ...

  9. js- 引用和复制(传值和传址)

    js- 引用和复制(传值和传址) 好像一般很少人讲到js中的引用和复制,不过弄清楚这个概念可以帮助理解很多东西 先讲一下很基础的东西,看看js中几种数据类型分别传的什么引用:对象.数组.函数复制:数字 ...

随机推荐

  1. [转载]eclipse的远程调试功能配置

    原文地址:eclipse的远程调试功能配置作者:我的 用途:web应用部署并运行于外部(区别于eclipse环境中启动的)应用服务器中,当出现问题时,可以使用eclipse工程的源代码进行跟踪调试. ...

  2. tensorflow内存溢出问题

    Tensorflow的静态图结构简洁清晰,符合人的思维.虽然编程上略微有些复杂,但是原理很容易看懂. Tensorflow分建图过程和运行图(张量求值)两个阶段,在这两个阶段中都可以定义操作和张量.但 ...

  3. NSOperation, NSOperationQueue 原理探析

    通过GNUstep的Foundation来尝试探索下NSOperation,NSOperationQueue 示例程序 写一个简单的程序 - (void)viewDidLoad { [super vi ...

  4. 我在阿里这仨月 前端开发流程 前端进阶的思考 延伸学习的方式很简单:google 一个关键词你能看到十几篇优秀的博文,再这些博文中寻找新的关键字,直到整个大知识点得到突破

    我在阿里这仨月 Alibaba 试用期是三个月,转眼三个月过去了,也到了转正述职的时间.回想这三个月做过的事情,很多很杂,但还是有重点. 本文谈一谈工作中遇到的各种场景,需要用到的一些前端知识,以及我 ...

  5. 神文章1:去年(2011)一年干了些啥? -vivo神人

    评论: 来自豆瓣的vivo神人,之前不知道有着一号牛逼的人物,觉此人博学.有正义感,其中有一片文章述说了中国近代经济演变历史情况,于我感触很深.因时间关系,没通读,有时间一定读完(微博口水杂录简略看了 ...

  6. python中,花括号,中括号,小括号的区别

    python中,花括号,中括号,小括号的区别 Python主要有三种数据类型:字典.列表.元组.其分别由花括号,中括号,小括号表示. 如: 字典:dic={'a':12,'b':34} 列表:list ...

  7. 如果没有 Android 世界会是什么样子?

    2005年谷歌从安迪·鲁宾(Andy Rubin)手中收购Android系统,起初安迪·鲁宾(Andy Rubin)只是想为数码相机开发出一个更为先进的系统,所以有了 Android.但是智能手机行业 ...

  8. Python ---chart

    # -*- coding:utf-8 -*- import random import matplotlib.pyplot as plt from pylab import * import os i ...

  9. Python - 列表解析式/生成器表达式

    列表解析式: [expr for iter_var in iterable if cond_expr] 生成器表达式: (expr for iter_var in iterable if cond_e ...

  10. 【转载】Eclipse中.setting目录下文件介绍

    原文:http://blog.csdn.net/huaweitman/article/details/52351394 Eclipse在新建项目的时候会自动生成一些文件.这些文件比如.project. ...