函数的参数到底是传递的一份复制的值,还是对内存的引用?

我们看下面一段代码:

a = []
def fun(x):
x.append(1)
fun(a)
print(a)

  想想一下:如果传递的是一份复制的值,那么列表a应该是不会变化的,还是空列表;如果传递的是引用,那么a应该是[1]。

执行一下看到输出结果是[1],即证明函数参数传递的是引用。

但是,再看下面的代码:

a = 1
def fun(x):
x = 2
return x
ret = fun(a)
print(a)
print(ret)

  如果按照上面的理解,函数参数传递的是引用,那么a的值应该变为2,但是输出却是1,这是为什么?

解释:

    python中所有的变量都可以理解是内存中一个对象的“引用”。这里需要记住的是类型是属于对象的,而不是变量。而对象有两种,“可更改”(mutable)与“不可更改”(immutable)对象。在python中,strings, tuples, 和numbers是不可更改的对象,而list,dict等则是可以修改的对象。(这就是这个问题的重点)

    当一个引用传递给函数的时候,函数自动复制一份引用,这个函数里的引用和外边的引用没有半毛关系了。所以第二个例子里函数把引用指向了一个不可变对象,当函数返回的时候,外面的引用是不会改变的。而第一个例子就不一样了,函数内的引用指向的是可变对象,对它的操作就和定位了指针地址一样,在内存里进行修改。

    不过,有的时候我们确实需要在函数内部修改全局的不可修改的对象,这个时候怎么办呢?

a = 1
def fun(x):
global a
x = 2
a = 'hello'
return x
ret = fun(a)
print(a)
print(ret)

  输出:

hello
2

    我们看到通过关键字global,我们将a的值做了修改。但是我们建议尽量减少这种方式的使用,因为我们在函数内部修改了全局变量的值,如果后面还有其他函数使用这个变量的时候可能还认为a的值是1,因此导致出错,而且不易排查。

    另:全局变量约定使用大写字母。

**Python的函数参数传递 和 global的更多相关文章

  1. 1.python的函数参数传递

    1 Python的函数参数传递 看两个例子: a = 1 def fun(a): a = 2 fun(a) print a # 1 a = [] def fun(a): a.append(1) fun ...

  2. python中函数参数传递的几种方法

    转自  http://www.douban.com/note/13413855/ Python中函数参数的传递是通过“赋值”来传递的.但这条规则只回答了函数参数传递的“战略问题”,并没有回答“战术问题 ...

  3. Python中函数参数传递问题【转】

    1. Python passes everything the same way, but calling it "by value" or "by reference& ...

  4. python 中函数参数传递形式

    python中函数参数的传递是通过赋值来传递的.函数参数的使用又有俩个方面值得注意:1.函数参数是如何定义的 2.在调用函数的过程中参数是如何被解析 先看第一个问题,在python中函数参数的定义主要 ...

  5. Python中函数参数传递问题

    先上两个例子: http://python.jobbole.com/85231/ a = 1 def fun(a): a = 2 fun(a) print a # 结果为1 fun(a)中的a,可以看 ...

  6. 跟着太白老师学python day10 函数嵌套, global , nonlocal

    函数嵌套: 第一种嵌套方法 def func(): count = 123 def inner(): print(count) inner() func() 第二种嵌套方法 count = 123 d ...

  7. Python的函数参数传递

    a = 1 def fun(a): a = 2 fun(a) print a # 1 a = [] def fun(a): a.append(1) fun(a) print a # [1]

  8. Python 函数参数传递机制.

    learning python,5e中讲到.Python的函数参数传递机制是对象引用. Arguments are passed by assignment (object reference). I ...

  9. Python语言特性之1:函数参数传递

    问题:在Python文档中好像没有明确指出一个函数参数传递的是值传递还是引用传递.如下面的代码中"原始值"是不放生变化的: class PassByReference: def _ ...

随机推荐

  1. linux下修改了tomcat端口之后无法访问

    查看防火墙,是否将修改之后的端口加入防火墙规则内,如没有,加入规则内,重启防火墙,如果还是无法访问,请看第二步 执行bin目录下shutdown.sh脚本,如果正常关闭,则执行startup.sh脚本 ...

  2. 新的开源java反汇编程序Procyon

    wiki:https://bitbucket.org/mstrobel/procyon/wiki/Java%20Decompiler 由于jd好多年没更新了,今天找到这个新的开源反汇编,很不错 分享一 ...

  3. BZOJ5298 CQOI2018 交错序列 【DP+矩阵快速幂优化】*

    BZOJ5298 CQOI2018 交错序列 [DP+矩阵快速幂优化] Description 我们称一个仅由0.1构成的序列为"交错序列",当且仅当序列中没有相邻的1(可以有相邻 ...

  4. .NET中的那些受特别对待的类型(CriticalFinalizerObject)

    转自:http://www.cnblogs.com/yuyijq/archive/2009/08/09/1542435.html 股票里面有个ST股,就是Special Treatment的意思.就是 ...

  5. HDFS原理分析之HA机制:avatarnode原理

    一.问题描述 由于namenode 是HDFS的大脑,而这个大脑又是单点,如果大脑出现故障,则整个分布式存储系统就瘫痪了.HA(High Available)机制就是用来解决这样一个问题的.碰到这么个 ...

  6. Linux安装vsftpd总结

    我使用的是CentOS6安装的vsftpd,转载请注明出处,以下是我的记录: #查看是否已经安装了vsfptd vsftpd -v #安装 yum -y install vsftpd #创建:chro ...

  7. win32窗口样式GWL_EXSTYLE

    Private Const GWL_STYLE = (-16)             '窗口样式 '窗口风格Private Const WS_CAPTION = &HC00000       ...

  8. css animation动画

    css 动画: 动画是CSS3中具有颠覆性的特征之一,可通过设置多个节点来精确控制一个或一组动画,常用来实现复杂的动画效果. 必要元素: a.通过@keyframes指定动画序列:自动补间动画,确定两 ...

  9. 自定义vue全局组件use使用(解释vue.use()的原理)

    我们在前面学习到是用别人的组件:Vue.use(VueRouter).Vue.use(Mint)等等.其实使用的这些都是全剧组件,这里我们就来讲解一下怎么样定义一个全局组件,并解释vue.use()的 ...

  10. k8s helm 包管理私服chartmuseum 安装

    备注:   预备环境需要安装helm  1. 安装chartmuseum  参考 # on Linux curl -LO https://s3.amazonaws.com/chartmuseum/re ...