洗礼灵魂,修炼python(22)--自定义函数(3)—函数作用域,闭包
前面你看到嵌套两层的函数,也许你有感而发,想来点刺激的对不?那么如果每层内的变量名如果相同会怎样?拿个例子看下就知道:

报错了,报错信息大意是,本地变量‘num’引用前没有被赋值定义。这咋回事,我外层不是定义了吗?这个问题就涉及到今天要说的话题——函数作用域
函数作用域
1.作用域分三个:本地作用域(local),函数内作用域(enclosing),全局作用域(global)
2.三个作用域的优先级规则是这样:L>E>G>B
这里的B是什么呢?是Built-in,眼熟不,好像在哪里用过对吧?我们查看内置函数的命令是什么?dir(__builtins__)对吧?对了,就是这个,这个是内置作用域,知道就行,一般不会拿出来与前面三个作用域做比较
3.包含关系:

4.函数定义了本地作用域,模块定义了全局作用域:
1):每个模块都是一个全局作用域,所以全局作用域的范围是单个程序文件
2):每次对函数的调用都会创建一个新的本地作用域,赋值的变量除非声明为全局变量,否则均为本地变量
3):所有的变量名都可以归纳为本地,全局或内置(由__builtin__模块提供)
4):任何的函数在调用结束后,其内的变量都是消失
5.因为有了三个作用域,则会产生全局变量,局部变量
1)全局变量:指除了函数内的外层变量
2)局部变量:指函数内部的变量
6.局部变量和全局变量互不影响,即使变量名相同也如此。
看完以上的概念,上面的例子为何出错应该很好理解了。
在函数内修改外部的全局变量是不可行的,因为python会自动屏蔽掉,但函数内部都可以访问全局变量。
怎么屏蔽的呢?在函数内部创建一个与全局变量相同的局部变量来屏蔽,当你调用时因为优先级关系会自动的调用函数内部的那个变量,而外层的同名变量则永远也不会被调用
例:

结果显而易见,num并没有被改掉,这就是屏蔽的效果。num=100这个变量为全局变量,而函数temp内的num=50是局部变量。
那么我确实想改呢?方法是有的,加入一个global参数即可,例:

注意:global关键词不能写成 【global num=50 】,必须分开写,不然报错
改了对吧?但其实你有没有发现,其实是局部变量把全局变量改了,调用函数后,全局变量就变了
那假如我不给global是什么结果:

由此可以看出,在python中,函数内调用函数外的变量是可以的,当内部没有此变量时,会自动由优先级高到低一一审查,如果这个变量事先确实没有定义,才抛出一个错误【此变量没有被定义】。同时,我还要补充一点的是,代码运行方式是由上而下的,由上面两个例子可以看出。
那么你也许会想,因为上面的例子是局部变量改全局变量,我能不能全局变量改函数内的局部变量呢?这个问题留着,自己下去测试体会
那么既然有global,有没有和global类似的另一个关键词呢?有的——nonlocal,这里暂且不说,下面在合适的地方提到
7.内嵌函数:内嵌函数前面其实也提到了一点,就是函数内再嵌套一层或者多层函数,这种就叫内嵌函数
例:

注意:
1).在最后必须加入inn()这段代码,这才是调用inn函数的命令
2).调用函数只能调用外层函数,不能直接调用内层函数,不然报错,因为内部函数整作用域都在外部函数之内

3).inn()的调用并且是在out函数层内加入,而非在inn函数层加,如果不加入,则:

再看一个例子:

这里例子也很经典,符号‘.’是类的方法的调用【类在后面会讲到】,而此时是函数,函数的调用时是使用符号‘()’,所以以上代码就好解释了
注意,由于前面说的【任何函数调用结束时,其内的变量消失】,但此时的a1是对f1的调用,f1调用完变量就消失,而此时的a1调用时变量还在,因为在函数嵌套时,还有一层函数,所以并没有消失。
所以,总结:如果调用函数是直接返回内层函数(比如这里的a1函数调用),内层会自动记忆外层函数变量,这种行为就是函数的闭包(也叫闭合),也就是所谓的工厂函数
下一篇博文详细介绍闭包问题
洗礼灵魂,修炼python(22)--自定义函数(3)—函数作用域,闭包的更多相关文章
- Python开发——函数【装饰器、高阶函数、函数嵌套、闭包】
装饰器 装饰器本质就是函数,为其他函数添加附加功能. 原则: 不修改被修饰函数的源代码 不修改被修饰函数的调用方法 装饰器知识储备:装饰器 = 高阶函数 + 函数嵌套 + 闭包 案例:求函数运行时间! ...
- 洗礼灵魂,修炼python(20)--自定义函数(1)—基础概念
作为开发,那么我们前面学的那些知识其实够了,但是不够精简,也不好维护,比如需要打印斐波那契数列: 而当我们需要再次打印斐波那契数列,又要把这段代码加上,是不是很烦,有没有方法可以解决,当然可以,那就是 ...
- 洗礼灵魂,修炼python(24)--自定义函数(5)—匿名函数lambda
在这个互联网时代,大家都喜欢匿名,匿名上网,匿名登录,匿名操作等等,都不喜欢实名对吧?(虽然说现在实名制已经快到来,题外话,扯远了),当然python里也有个不喜欢实名的,它的功效优点特殊,说强大吧? ...
- 洗礼灵魂,修炼python(5)--python操作符,内置函数
前面提到了BIF(内置函数)这个概念,什么是内置函数,就是python已经定义好的函数,不需要人为再自己定义,直接拿来就可以用的函数,那么都有哪些BIF呢? 可以在交互式界面(IDLE)输入这段代码, ...
- 洗礼灵魂,修炼python(85)-- 知识拾遗篇 —— 深度剖析让人幽怨的编码
编码 这篇博文的主题是,编码问题,老生常谈的问题了对吧?从我这一套的文章来看,前面已经提到好多次编码问题了,的确这个确实很重要,这可是难道了很多能人异士的,当你以为你学懂了,在研究爬虫时你发现你错了, ...
- 洗礼灵魂,修炼python(69)--爬虫篇—番外篇之feedparser模块
feedparser模块 1.简介 feedparser是一个Python的Feed解析库,可以处理RSS ,CDF,Atom .使用它我们可从任何 RSS 或 Atom 订阅源得到标题.链接和文章的 ...
- 洗礼灵魂,修炼python(40)--面向对象编程(10)—定制魔法方法+time模块
定制魔法方法 1.什么是定制魔法方法 首先定制是什么意思呢?其实就是自定义了,根据我们想要的要求来自定义.而在python中,其实那些所谓的内置函数,内置方法,内置属性之类的其实也是自定义出来的,不过 ...
- 洗礼灵魂,修炼python(6)--活起来的代码+列表
活起来的用法: 使用input内置函数 注意python2中和python3中,input函数是不太一样的,python2中,input用户传入什么类型就是什么类型而python3中,不管传入什么类型 ...
- 洗礼灵魂,修炼python(29)--装饰器(1)—>利用经典案例解析装饰器概念
前提必备 不急着进入正题,在前面函数作用域那一章介绍了闭包,全局变量局部变量,这里再看几个简单的闭包案例: 1):不带参数 注意: 1.这里的name属性是每个函数都有的,可以反馈函数名 2.temp ...
随机推荐
- 求一个集合的所有真子集 Python
给定一个集合,元素均为正整数且不重复,求该集合的所有子集 # -*- coding: utf-8 -*- """ Created on Tue Oct 10 09:04: ...
- 课程四(Convolutional Neural Networks),第三 周(Object detection) —— 2.Programming assignments:Car detection with YOLOv2
Autonomous driving - Car detection Welcome to your week 3 programming assignment. You will learn abo ...
- 树莓派安装vnc server并设置自启动
在SSH终端输入sudo raspi-config, 这里需要打开几个选项: expand_rootfs – 将根分区扩展到整张SD卡; change_pass – 默认的用户名是pi,密码是rasp ...
- nginx ngx_http_sub_module使用
ngx_http_sub_module模块是一个过滤器,它修改网站响应内容中的字符串,比如你想把响应内容中的‘iuwai’全部替换成‘aaaaa‘,这个模块已经内置在nginx中,但是默认未安装,需要 ...
- MySQL 设计规范
一.数据库命令规范 所有数据库对象名称必须使用小写字母并用下划线分割 所有数据库对象名称禁止使用mysql保留关键字(如果表名中包含关键字查询时,需要将其用单引号括起来) 数据库对象的命名要能做到见名 ...
- MySQL中的事务及读写锁实现并发访问控制
一.并发控制中锁的概念 锁是并发控制中最核心的概念之一,在MySQL中的锁分两大类,一种是读锁,一种是写锁,读锁也可以称为共享锁(shared lock),写锁也通常称为排它锁(exclusive l ...
- [design-patterns]设计模式之一策略模式
设计模式 从今天开始开启设计模式专栏,我会系统的分析和总结每一个设计模式以及应用场景.那么首先,什么是设计模式呢,作为一个软件开发人员,程序人人都会写,但是写出一款逻辑清晰,扩展性强,可维护的程序就不 ...
- centos每天自动备份mysql数据库
#!/bin/bash PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin export PATH #数据库用户名 db ...
- 前端迷思与React.js
前端迷思与React.js 前端技术这几年蓬勃发展, 这是当时某几个项目需要做前端技术选型时, 相关资料整理, 部分评论引用自社区. 开始吧: 目前, Web 开发技术框架选型为两种的占 80% .这 ...
- IIS7 开发与 管理 编程 之 Microsoft.Web.Administration
一.引言: 关于IIS7 Mocrosoft.Web.Administration 网上这方面详细资料相对来说比较少,大家千篇一律的(都是一篇翻译过来的文章,msdn 里面的实列没有).前段做了一个 ...