全局变量:在定义的时候,顶头写的,没有任何缩进的变量就是全局变量。

全局变量的特点:在当前文件里的任何地方都可以进行调用

局部变量:在子程序里定义的变量,就是局部变量。

子程序:比如.py文件里,写的函数就是个子程序。而这个函数里定义的变量就是局部变量

示例:全局变量

  1. # 全局变量
  2. name='alex'
  3.  
  4. def change_name():
  5. print('change_name',name) # 调用了全局变量
  6.  
  7. change_name()
  8. # 结果
  9. change_name alex
  10.  
  11. print(name) #调的是全局变量
  12. # 结果
  13. alex

示例:函数体内定义局部变量

  1. # 全局变量:全局作用域
  2. name='alex'
  3.  
  4. def change_name():
  5. name='帅呆了' # 局部变量:局部作用域
  6. print('change_name',name) # 先在自己的子程序里找,调用了局部变量
  7.  
  8. # 举个生活中的例子,刚起床找手机,肯定现在自己卧室(函数)找,自己卧室找不到,才可能会到卧室(函数之外)之外去找。
  9. # 所以,很好的理解,就是优先内部,然后外部;局部变量只能该函数自己使用(私心重),全局变量就比较大方,谁需要就可以拿去用
  10.  
  11. change_name()
  12. # 结果
  13. change_name 帅呆了
  14.  
  15. print(name) #调的是全局变量
  16. # 结果
  17. alex

示例:函数体内声明全局变量

  1. # 全局变量
  2. name='alex'
  3.  
  4. def change_name():
  5. global name # 函数体内声明了全局变量
  6. name='帅呆了' # 函数体内修改了全局变量的值
  7. print('change_name',name) # 调用了全局变量
  8.  
  9. change_name()
  10. # 结果
  11. change_name 帅呆了
  12.  
  13. print(name) #调的是全局变量,但是全局变量的值已经被修改
  14. # 结果
  15. 帅呆了

更好的示例

如果函数的内容无global关键字,优先读取局部变量;如果没有局部变量,只能读取全局变量,无法对全局变量重新赋值,但于可变类型,是可以对内部元素进行操作

如果函数的内容有global关键字,函数内的变量就是全面局变量,可以读取,可以赋值

  1. name = "桃花李"
  2.  
  3. def yangjian():
  4. global name # 已经声明,NAME就是全局的的那个变量
  5. print('我要', name)
  6. name = "小东北" # 修改 全局的变量
  7. print('我要', name)
  8.  
  9. def qupengfei():
  10. name = "基"
  11. print('我要搞', name)
  12.  
  13. yangjian()
  14. qupengfei()
  15.  
  16. #结果
  17. 我要 桃花李
  18. 我要 小东北
  19. 我要搞

总结

  1. 全局变量变量名大写
    局部变量变量名小写
  1. 下面的示例为了说明全局变量和局部变量的关系,都用的是大写。
  2. # 如果函数的内容无global关键字:
  3. # - 有声明局部变量
  4. NAME = ["产品经理","廖波湿"]
  5. def qupengfei():
  6. NAME = "自己"
  7. print('我要搞', NAME)
  8. qupengfei()
  9.  
  10. # - 无声明局部变量
  11. NAME = ["产品经理","廖波湿"]
  12. def qupengfei():
  13. NAME.append('XXOO')
  14. print('我要搞', NAME)
  15. qupengfei()
  16.  
  17. # 如果函数的内容有global关键字
  18. # - 有声明局部变量
  19. NAME = ["产品经理","廖波湿"]
  20. def qupengfei():
  21. global NAME
  22. NAME = "自己"
  23. print('我要搞', NAME)
  24. qupengfei()
  25.  
  26. # 错误示例, 全部变量放在了局部变量的下面,是不行的;所以,如果要什么全局变量,就尽量往前放。
  27. NAME = ["产品经理","廖波湿"]
  28. def qupengfei():
  29. NAME = "自己"
  30. global NAME
  31. print('我要搞', NAME)
  32. qupengfei()
  33.  
  34. # - 无声明局部变量
  35. NAME = ["产品经理","廖波湿"]
  36. def qupengfei():
  37. global NAME
  38. NAME = ["阿毛"]
  39. NAME.append('XXOO')
  40. print('我要搞', NAME)
  41. qupengfei()

函数里也可以嵌套函数,执行顺序如下图所示

  1. name='海风'
  2. def huangwei():
  3. name = "黄伟"
  4. print(name)
  5. def liuyang():
  6. name = "刘洋"
  7. print(name)
  8. def nulige():
  9. name = '炉指花'
  10. print(name)
  11. print(name)
  12. nulige()
  13. liuyang()
  14. print(name)
  15.  
  16. huangwei()
  17. # 结果
  18. 黄伟
  19. 刘洋
  20. 刘洋
  21. 炉指花
  22. 黄伟

  1. name = "刚娘"
  2.  
  3. def weihou():
  4. name = "陈卓"
  5. def weiweihou():
  6. global name # global,声明的是全局变量,
  7. name = "冷静" # 此处修改的是最外层的全局变量,而不是它上一级同名变量
  8. weiweihou()
  9. print(name)
  10. print(name)
  11. weihou()
  12. print(name)
  13.  
  14. #结果
  15. 刚娘
  16. 陈卓
  17. 冷静

  1. name = "刚娘"
  2.  
  3. def weihou():
  4. name = "陈卓"
  5. def weiweihou():
  6. nonlocal name # nonlocal,指定上一级变量,如果没有就继续往上直到找到为止
  7. name = "冷静"
  8. weiweihou()
  9. print(name)
  10.  
  11. print(name)
  12. weihou()
  13. print(name)
  14.  
  15. # 结果
  16. 刚娘
  17. 冷静
  18. 刚娘

 前向引用(野路子好记,别名风湿理论):函数即变量

  1. def foo():
  2. print('from foo')
  3. bar()
  4.  
  5. def bar():
  6. print('from bar')
  7.  
  8. foo()
  9. # 结果
  10. from foo
  11. from bar
  1. def foo():
  2. print('from foo')
  3. bar()
  4.  
  5. foo()
  6. # 结果
  7. 程序报错,因为没有定义bar()
  1. def foo():
  2. print('from foo')
  3. bar()
  4.  
  5. foo()
  6.  
  7. def bar():
  8. print('from bar')
  9.  
  10. # 结果
  11. 报错,即使定义了bar(),但是他放在了foo()调用的后面,也不会执行

  1. # 用前向引用解释函数嵌套的调用

    name='海风'
  2. def huangwei():
  3. name = "黄伟"
  4. print(name)
  5. def liuyang():
  6. name = "刘洋"
  7. print(name)
  8. def nulige():
  9. name = '炉指花'
  10. print(name)
  11. print(name)
  12. nulige()
  13. liuyang()
  14. print(name)
  15.  
  16. print(name)
  17. huangwei()
  18. print(name)
  19.  
  20. # 结果
  21. 黄伟
  22. 刘洋
  23. 刘洋
  24. 炉指花
  25. 黄伟
  26. 海风

函数递归

递归就好比你去问A腾达大厦怎么走?A说我不知道,我去问问B,B说完我也不知道,我去问问C,然后C又去问D,D说我知道,告诉了C,C又告诉了B,B告诉了A,A把最后的结果返回给了你。

递归特性:

1. 必须有一个明确的结束条件

2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少

3. 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)

堆栈扫盲http://www.cnblogs.com/lln7777/archive/2012/03/14/2396164.html 

尾递归优化:http://egon09.blog.51cto.com/9161406/1842475

示例:

递归函数内部,有自己调用自己,就会形成一个循环,一直循环下去, 最后报错

  1. def calc(n):
  2. print(n)
  3. calc(n)
  4.  
  5. calc(10)
  6.  
  7. #结果
  8. 10
  9. 10
  10. ...10
  11. RecursionError: maximum recursion depth exceeded while calling a Python object
  1. def calc(n):
  2. print(n)
  3. if int(n/2) ==0:
  4. return n
  5. return calc(int(n/2))
  6.  
  7. calc(10)
  8.  
  9. 输出:
  10. 10
  11. 5
  12. 2
  13. 1
  1. # 以问路的生活实例来解释递归函数
  2. import time
  3.  
  4. # 问路,得先有问的人,需要定义一个列表
  5. person_list=['alex','wupeiqi','yuanhao','linhaifeng''sb’]
  6. #
  7. def ask_way(person_list):
  8. print('-'*60)
  9. if len(person_list) == 0: # 该条件表示该问的人都问完了,没人知道路
  10. return '没人知道' # 终止
  11. person=person_list.pop(0) # 一次弹出一个人
  12. if person == 'linhaifeng': # 该条件表示这个人知道路
  13. return '%s说:我知道,老男孩就在沙河汇德商厦,下地铁就是' %person
  14. print('hi 美男[%s],敢问路在何方' %person)
  15. print('%s回答道:我不知道,但念你慧眼识猪,你等着,我帮你问问%s...' %(person,person_list))
  16. time.sleep(3)
  17. res=ask_way(person_list)
  18. print('%s问的结果是: %res' %(person,res))
  19. return res
  20.  
  21. res=ask_way(person_list)
  22. print(res)
  23.  
  24. # 结果
  25. ------------------------------------------------------------
  26. hi 美男[alex],敢问路在何方
  27. alex回答道:我不知道,但念你慧眼识猪,你等着,我帮你问问['wupeiqi', 'yuanhao', 'linhaifeng', 'zsc']...
  28. ------------------------------------------------------------
  29. hi 美男[wupeiqi],敢问路在何方
  30. wupeiqi回答道:我不知道,但念你慧眼识猪,你等着,我帮你问问['yuanhao', 'linhaifeng', 'zsc']...
  31. ------------------------------------------------------------
  32. hi 美男[yuanhao],敢问路在何方
  33. yuanhao回答道:我不知道,但念你慧眼识猪,你等着,我帮你问问['linhaifeng', 'zsc']...
  34. ------------------------------------------------------------
  35. yuanhao问的结果是: 'linhaifeng说:我知道,老男孩就在沙河汇德商厦,下地铁就是'es
  36. wupeiqi问的结果是: 'linhaifeng说:我知道,老男孩就在沙河汇德商厦,下地铁就是'es
  37. alex问的结果是: 'linhaifeng说:我知道,老男孩就在沙河汇德商厦,下地铁就是'es
  38. linhaieng说:我知道,老男孩就在沙河汇德商厦,下地铁就是

第十二篇 Python函数之全局变量&局部变量&递归函数的更多相关文章

  1. Python开发【第二十二篇】:Web框架之Django【进阶】

    Python开发[第二十二篇]:Web框架之Django[进阶]   猛击这里:http://www.cnblogs.com/wupeiqi/articles/5246483.html 博客园 首页 ...

  2. Python之路【第十二篇】:JavaScrpt -暂无内容-待更新

    Python之路[第十二篇]:JavaScrpt -暂无内容-待更新

  3. 跟我学SpringCloud | 第十二篇:Spring Cloud Gateway初探

    SpringCloud系列教程 | 第十二篇:Spring Cloud Gateway初探 Springboot: 2.1.6.RELEASE SpringCloud: Greenwich.SR1 如 ...

  4. 第十二章 Python文件操作【转】

    12.1 open() open()函数作用是打开文件,返回一个文件对象. 用法格式:open(name[, mode[, buffering[,encoding]]]) -> file obj ...

  5. Mysql优化(出自官方文档) - 第十二篇(优化锁操作篇)

    Mysql优化(出自官方文档) - 第十二篇(优化锁操作篇) 目录 Mysql优化(出自官方文档) - 第十二篇(优化锁操作篇) 1 Internal Locking Methods Row-Leve ...

  6. 解剖SQLSERVER 第十二篇 OrcaMDF 行压缩支持(译)

    解剖SQLSERVER 第十二篇   OrcaMDF 行压缩支持(译) http://improve.dk/orcamdf-row-compression-support/ 在这两个月的断断续续的开发 ...

  7. 第十二篇 SQL Server代理多服务器管理

    本篇文章是SQL Server代理系列的第十二篇,详细内容请参考原文 在这一系列的上一篇,我们查看了维护计划,一个维护计划可能会创建多个作业,多个计划.你还简单地看了SSIS子系统,并查看了维护计划作 ...

  8. 第十二篇 Integration Services:高级日志记录

    本篇文章是Integration Services系列的第十二篇,详细内容请参考原文. 简介在前一篇文章我们配置了SSIS内置日志记录,演示了简单和高级日志配置,保存并查看日志配置,生成自定义日志消息 ...

  9. 【译】第十二篇 Integration Services:高级日志记录

    本篇文章是Integration Services系列的第十二篇,详细内容请参考原文. 简介在前一篇文章我们配置了SSIS内置日志记录,演示了简单和高级日志配置,保存并查看日志配置,生成自定义日志消息 ...

随机推荐

  1. Java并发程序基础

    Thread.stop() 直接终止线程,并且会立即释放这个线程所持有的锁. Thread.interrupt() 并不会是线程立即退出,而是给线程发送一个通知,告知目标线程,有人希望你退出啦,至于目 ...

  2. HDU1214 圆桌会议(找规律,数学)

    传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1214 圆桌会议 Time Limit: 2000/1000 MS (Java/Others)    M ...

  3. OS_EVENT 信号量

    1.   OS_EVENT *T2sem=(OS_EVENT *)0; 这句代码的意思是 把OS_EVENT类型的一个指针T2sem赋值为0: 其中 OS_EVENT是数据类型,*代表是指针类型,(O ...

  4. JavaScript编写棋盘覆盖

    一.前言 之前做了一个算法作业,叫做棋盘覆盖,本来需要用c语言来编写的,但是因为我的c语言是半桶水(哈哈),所以索性就把网上的c语言写法改成JavaScript写法,并且把它的覆盖效果显示出来 二.关 ...

  5. 如何配置Java环境变量

    百度经验 | 百度知道 | 百度首页 | 登录 | 注册 新闻 网页 贴吧 知道 经验 音乐 图片 视频 地图 百科 文库 帮助   发布经验 首页 分类 任务 回享 商城 特色 知道 百度经验 &g ...

  6. Oracle之视图

    Oracle之视图 2018.9.12 由于视图的数据与表数据互相关联,所以切记谨慎操作 建立视图 使用下面sql语句来完成视图的创建 create or replace view 视图名 as se ...

  7. 微信小程序学习笔记(一)

    1.目录及文件构成 1.1 根目录下 ** app.js 是小程序的脚本代码,用来监听并处理小程序的生命周期函数.声明全局变量. ** app.json 是对整个小程序的全局配置,配置小程序是由哪些页 ...

  8. JavaScript 基础(一)

    基本语法: 区分大小写: ECMAScript 中的一切(变量,函数名和操作符)都区分大小写. 标识符: 表示符就是指,变量,函数,属性名字,或者函数的参数. 1.第一个字符必须是一个字母,下划线(_ ...

  9. 前端关于SEO

    提高页面加载速度. 能用css解决的不用背景图片,背景图片也尽量压缩大小,可以几个icons放在一个图片上,使用background-position找到需要的图片位置.可以减少HTTP请求数,提高网 ...

  10. Java解决跨域问题

    同源 URL由协议, 域名, 端口组成. 如果两个URL的协议, 域名, 端口相同, 那么这两个URL为同源. 同源策略 script, iframe, link 可以跨域加载一些静态资源, 比如脚本 ...