**Python的函数参数传递 和 global
2024-10-20 09:25:14
函数的参数到底是传递的一份复制的值,还是对内存的引用?
我们看下面一段代码:
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,因此导致出错,而且不易排查。
另:全局变量约定使用大写字母。
最新文章
- VS2010编写WebService与在IIS的发布<;之简单讲解>;
- Markdown简单语法
- MySql: log 位置
- RHEL7 CentOS7 检查查看精简指令
- 【BZOJ】3994: [SDOI2015]约数个数和
- Silverlight 调用自托管的wcf 报跨域异常的处理
- python先序、中序、后序排序
- P6 EPPM Manual Installation Guide (Oracle Database)
- B/S C/S架构的界面测试
- centos vpn
- NSString copy or not (strong)?
- [翻译] 编写高性能 .NET 代码--第二章 GC -- 减少分配率, 最重要的规则,缩短对象的生命周期,减少对象层次的深度,减少对象之间的引用,避免钉住对象(Pinning)
- Linux OpenGL 实践篇-1 OpenGL环境搭建
- Swift构造
- Emmet(以前的Zencoding)的使用
- canvas背景动画
- Pfsense2.34中文版
- springboot+freemarker
- PID控制器开发笔记之七:微分先行PID控制器的实现
- 浅析软件工程中的UML建模技术
热门文章
- Failed to instantiate the default view controller for UIMainStoryboardFile &#39;Main&#39; - perhaps the designated entry point is not set?
- [转]Java 8新特性探究(lambda)
- 值类型struct在foreach中的陷阱
- LG3690 【模板】Link Cut Tree (动态树)
- php用smtp方式发送邮件
- 高并发的epoll+线程池,线程池专注实现业务
- 常见企业IT支撑【3、SVN代码版本控制系统】
- 类的声明与实例化及构造方法析构方法(PHP学习)
- SAX解析类:SaxHelper
- ContentProvider用法