博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python函数调用中全局变量与局部变量的分析与理解
阅读量:7172 次
发布时间:2019-06-29

本文共 1708 字,大约阅读时间需要 5 分钟。

此内容来自于沙行勉的《计算机科学导论-以python为舟》

  • 函数调用的基本概念:程序语言中的函数与高中数学中的函数相似。高中函数,假设要实现z+x*y²这个计算。对于乘法计算,定义一个函数f(x,y)=x*y²,他有两个参数x和y。计算x²+y²后得到一个值,作为函数的返回值,赋给f(x,y)。这样就可以用z+f(x,y)来表示上面的运算,对于f(x,y)运算,将会调用到已经定义的函数f(x,y)=x*y²。程序语言中的函数也有参数和返回值,以及定义与调用。程序中的函数就是将一些程序语句结合在一起的部件,可以多次的调用。
  • 函数中的变量:

局部变量:函数中的局部变量只能被这个函数访问,不能被其他函数访问。

全局变量:在函数之外被赋值的变量。

a = 10def fun():    a = 20    print(a)    #函数内a内局部变量fun()print(a)        #函数外a为全局变量复制代码

  • 局部变量的判断:
  1. 不出现在global语句中 (global语句为申明某个变量为局部变量)
  2. 出现在函数参数中
  3. 出现在函数参数语句中的等号左边

  • python函数调用:

python进行函数调用时,参数的传递都是通过赋值的方式。

def func(L1):       #定义一个func()函数,参数为L1    L1.append(1)    #对L1采用.append()方法,结果为[2,1],并且改变全局变量L的值(因为L1和L都指向同一个heap)L = [2]             func(L)             #func()函数运行,参数为L,进行赋值传递给func()函数中的局部变量L,print(L)            func()函数执行完后,局部变量L1指向全局上的值[2,1],L也指向这个全局上的值[2,1](L1与L指向同一块内存区域)复制代码

其中列表做参数时,传递的是指针,函数中的参数指向的内容为全局变量区域,成为heap。

stack-栈,heap-堆

注意事项:

  1. 列表的append、pop、remove等方法,以及给L[i]赋值,对L[i]使用增强赋值等,都会修改列表L所指向的内容,进而对全局产生影响。
  2. 列表的一般合并,或者使用列表的分片(即L[i:j]这种形式)都不会对全局的列表L产生影响。合并与分片的操作会产生新的列表,赋值到一块新的内存区域(heap)上。

  • return(L)返回L的指针:

def F1():    L = [3,2,1,]    #L是局部变量,而[3,2,1]是在栈的外面heap上。    return(L)L = f1() print("L=",L)复制代码

全局变量L调用f1()函数,f1()函数中的局部变量L经return返回到函数外的全局变量L,此时局部变量L和全局变量L都指向同一个heap。

  • L做函数参数传递:

def F2():                  #参数L是个指针,是存放在栈上的局部变量    L = [2,1]              #此语句将函数L又赋值为[2,1]    return(L)              #return(L)将局部变量L的值赋值给了主调函数的全局变量(例如L = F2(),L是主调函数,F2()则是被调函数)def F3():                   L.append(1)            #L指向的是原来的全局内容,会改变全局L    L[0] = 0L = [3,2,1]               L = F2(L);print("L=",L)   F3(L);print("L=",L)         #调用F3(L)后,L的全局已经被改变复制代码

  • 好的编程习惯:
  1. 尽量避免在函数中使用全局变量
  2. 若在函数中需要使用外部的变量,使用参数传递。
  3. 对函数调用中mutable变量(列表、字典等)

转载于:https://juejin.im/post/5bd58d266fb9a05cf03a305c

你可能感兴趣的文章
Python的sys.argv使用说明 通过终端写入环境变量
查看>>
在Windows上安装Nexus
查看>>
Future模式 总结
查看>>
为什么我再也不想和 Google HR 交谈了
查看>>
byzx
查看>>
虫洞漏洞挖掘研究
查看>>
用mysql查询某字段是否有索引
查看>>
ubuntu 查看进程,查看服务
查看>>
Cisco DHCP Snooping + IPSG 功能实现
查看>>
Linux命令_用户身份切换
查看>>
学习在.NET Core中使用RabbitMQ之启动和基础(一)
查看>>
支付业务的数据库表的设计
查看>>
php面试题二--解决网站大流量高并发方案(从url到硬盘来解决高并发方案总结)...
查看>>
PHP 16 个编程法则
查看>>
【微信】2.微信小程序开发--官方开发工具使用说明
查看>>
RedisTemplate访问Redis数据结构
查看>>
面试如何回答优化数据库
查看>>
SuperSocket与Netty之实现protobuf协议,包括服务端和客户端
查看>>
ASP.NET CORE系列【二】使用Entity Framework Core进行增删改查
查看>>
js如何返回两个数的商的整数和余数部分?
查看>>