Python 基础之函数的嵌套与nonlocal修改局部变量及闭包函数
一.函数的嵌套
嵌套在外层,称之为外函数
嵌套在里层,称之为内函数
#例:
def outer():
def inner():
print("I'm inner")
def inn2():
print("12345")
inn2()
inner()
outer()
#inner()
(1)内部函数可以直接在函数外部调用吗 不可以
(2)调用外部函数后,内部函数可以在函数外部调用吗 不可以
(3)内部函数可以在函数内部调用吗 可以
(4)内部函数在函数颞部调用时,是否有先后顺序 不可以
#外部函数outer 里面是inner ,inner里面还嵌套一个smaller 内函数,调用smaller
#例:
#a = 17
def outer():
#a = 16
#id = 99
def inner():
#a = 15
def smaller():
#a = 10
print(id)
print("I'm smaller")
smaller()
inner()
outer()
#LEGB (就近找变量原则)
#寻找变量的调用顺序采用LEGB原则(即就近原则)
L -- Local(function): 当前函数内的作用域 (局部作用域) (局部命名空间)
E -- Enclosing function locals:外部嵌套函数的作用域 (嵌套作用域) (局部命名空间)
G -- Global(module) :函数外部所在的命名空间 (全局作用域) (全局命名空间)
B -- Builtin(Python):python内置模块的命名空间 (内建作用域) (内建命名空间)
依据就近原则, 从上往下 从里向外 依次寻找
#注意点
如果先前局部变量存在a,删除之后再获取就获取不到,
如果先前不存在该局部变量,默认向上按照LEGB原则依次寻找
#例:
a = 10
def func():
a = 20
del a
#print(a)
func()
print(a)
二.nonlocal 修改局部变量
nonlocal 专门用于修改局部变量
(1)它自动寻找上一层空间的局部变量用来修改
(2)不停的向上寻找
(3)如果再也找不到了,直接报错
#(1) nonlocal 符合LEGB原则
def outer():
a = 15
def inner():
nonlocal a
a = 17
print(a)
inner()
print(a)
outer()
#(2)nonlocal 修改的是局部变量,不是全局变量
a = 16
def outer():
a = 10
def inner():
#a = 11
def smaller():
nonlocal a
a +=3
print(a)
smaller()
inner()
outer()
#(3) 不是用nonlocal 是否可以修改局部变量?可以
def outer():
# a = 3
lst = [1,2,3,4,5]
def smaller():
lst[2] +=5
smaller()
print(lst)
outer()
三.闭包函数
闭包:
内函数使用了外函数的局部变量
并且外函数把内函数返回出来的过程是闭包
这个内函数叫做闭包函数
#(1) 基本语法
def outer():
a = 5
b = 6
#inner 是闭包函数
def inner():
print(a,b)
return inner
res = outer()
print(res)
res()
#获取闭包函数使用的变量: __closure__ ,cell_contents (了解)
tup = res.__closure__
print("=====1======")
print(tup)
#获取元组里面第一个元素
obj = tup[0]
print(obj)
#使用cell_contents来获取单元对象当中的值
res = obj.cell_contents
print(res)
obj2 = tup[1]
res2 = obj2.cell_contents
print(res2)
print("<======2=======>")
#闭包的特点:
内函数使用了外函数的局部变量,外函数的局部变量与内函数发生绑定,延长该变量的生命周期
(实际内存给它存储了这个值,暂时不释放)
#(2)闭包函数特点
#例:
def famil():
dejie = "one"
erjie = "two"
#money 局部变量因为在闭包函数中使用,于是发生绑定,延长该变量的生命周期
money = 100000
def dajie_hobby():
nonlocal money
money -=30000
print("大姐喜欢花钱,喜欢买兰博基尼,喜欢买channel,家里钱还剩下%d" % (money))
def erjie_hobby():
nonlocal money
money +=15000
print("二姐喜欢赚钱,,家里钱赚了现在变成%d钱" % (money))
def master():
#返回一个元组,元组里面的每一个元素是函数
return (dajie_hobby,erjie_hobby)
return master
func = famil()
tup = func()
print(tup)
#大姐函数
dajie = tup[0]
dajie()
#二姐函数
erjie = tup[1]
erjie()
输出结果为:
大姐喜欢花钱,喜欢买兰博基尼,喜欢买channel,家里钱还剩下70000
二姐喜欢赚钱,,家里钱赚了现在变成85000钱
Python 基础之函数的嵌套与nonlocal修改局部变量及闭包函数的更多相关文章
- day10-Python运维开发基础(函数嵌套、nonlocal声明局部变量、闭包、locals/globals、lambda表达式)
1. 函数的嵌套与nonlocal 声明局部变量 # ### 函数的嵌套 """ 函数和函数之间可以互相嵌套: 嵌套在内层的叫做内函数 乔涛在外层的叫做外函数 " ...
- 036-PHP闭包函数的域限制,与如何向闭包函数传递变量
<?php // 闭包函数的域限制,与如何向闭包函数传递变量 # 隐藏上面的代码,我们最后再来试下 function demo($ATxt) { $func = function () use ...
- 函数的名称空间,函数的嵌套(global, nonlocal),函数名的运用
一 函数的名称空间 内置空间:存放python解释器内置函数的空间 全局空间:py文件运行时开辟的,存放的是执行的py文件(出去函数内部)的所有的变量与值的对用关系,整个py文件结束后才会消失. 局部 ...
- 动态参数 名称空间 作用域 作用域链 加载顺序 函数的嵌套 global nonlocal 等的用法总结
03,动态参数 *args,**kwargs # 用户传入到函数中的实参数量不定时,或者是为了以后拓展,# 此时要用到动态参数*args,**kwargs(万能参数.)# *args接收的是所有的位置 ...
- Python基础库之jieba库的使用(第三方中文词汇函数库)
各位学python的朋友,是否也曾遇到过这样的问题,举个例子如下: “I am proud of my motherland” 如果我们需要提取中间的单词要走如何做? 自然是调用string中的spl ...
- python基础-requests模块、异常处理、Django部署、内置函数、网络编程
网络编程 urllib的request模块可以非常方便地抓取URL内容,也就是发送一个GET请求到指定的页面,然后返回HTTP的响应. 校验返回值,进行接口测试: 编码:把一个Python对象编码转 ...
- Python基础总结之第十一天开始【再深入一下函数,重新认识一下】(新手可相互督促)
感谢最近大家的关注,希望我的学习笔记对大家有帮助!也感谢各位的评论和推荐,请多多指教. 在重新认识函数之前,我们先看两个函数.一个是我们在前面笔记经常用到的print() :另一个是input() ...
- python基础之生成器表达式形式、面向过程编程、内置函数部分
生成器表达式形式 直接上代码 1 # yield的表达式形式 2 def foo(): 3 print('starting') 4 while True: 5 x=yield #默认返回为空,实际上为 ...
- 【Python基础学习二】定义变量、判断、循环、函数基本语法
先来一个愉快的Hello World吧,就是这么简单,不需要写标点符号,但是需要严格按照缩进关系,Python变量的作用域是靠tab来控制的. print("Hello World" ...
随机推荐
- PL2303HXA自2012已停产
解决"PL2303HXA自2012已停产,请联系供货商" USB不识别的问题: 问题是WIN10自带的驱动不兼容引起的,只能安装早期驱动,再驱动程序中选择旧版本驱动即可
- CentOS 7----Apache基于域名的虚拟主机配置
配置/etc/hosts文件,192.168.1.209 对应的域名如下: 192.168.1.209 www.name1.com 编辑每个域名的配置文件: <VirtualHost 192.1 ...
- C语言:将s所指字符串中下标为偶数同时ASCII值为奇数的字符删去,-将a所指字符串中的字符和b所指字符串中的字符的顺序交叉,-将形参s所指字符串中的所有数字字符顺序前移,
//函数fun功能:将s所指字符串中下标为偶数同时ASCII值为奇数的字符删去,s所指串中剩余的字符形成的新串放在t所指的数组中. #include <stdio.h> #include ...
- Django 字段中 null 和 blank的区别
blank 设置为 True 时,字段可以为空 设置为 False 时,字段是必须填写的 默认为 False null 设置为 True 时,数据库的字段允许为NULL,而且表单中的空值将会被存储为N ...
- Vue-路由传参query与params
注明:vue中 $router 和 $route 的区别 //$router : 是路由操作对象,只写对象 //$route : 路由信息对象,只读对象 //操作 路由跳转 this.$router. ...
- C# 抗变与协变的理解
我们知道 方法的参数是协变的: void display(shape o) 如果类Rectangle 继承于shape类,那我们可以给该方法传入Rectangle类的实例. 而方法的返回类型是抗变的, ...
- 4_3 救济金发放(UVa133)<子过程/函数设计>
为了缩短领救济品的队伍,NNGLRP决定了以下策略:每天所有来申请救济品的人会被放在一个大圆圈,面朝里面.标明一个人为编号1号,其他的就从那个人开始逆时针开始编号直到N.一个官员一开始逆时针数,数k个 ...
- python opencv:像素运算
以下运算两个图像的大小需要一样 算术运算: cv2.add(img1, img2):两个图像像素相加 cv2.subtract(img1, img2):两个图像像素相减 cv2.multiply(im ...
- openfire 安装配置时出现The Openfire database schema does not appear to be installed. Follow the installati错误的解决方案
最近再弄openfire用openLDAP整合,本来没整合的时候选的标准数据库没问题,但是现在用嵌入式数据库,就报错了,,, 报错原因:没有导入openfire的数据表 解放办法: 1.登陆数据库 , ...
- 寒假pta二
整除光棍 这里所谓的“光棍”,并不是指单身汪啦~ 说的是全部由1组成的数字,比如1.11.111.1111等.传说任何一个光棍都能被一个不以5结尾的奇数整除.比如,111111就可以被13整除. 现在 ...