装饰器学习笔记1:函数的作用域
来源:互联网 发布:mac dosbox debug.exe 编辑:程序博客网 时间:2024/06/04 22:49
恩,继续整理笔记,因为不熟练,感觉平时本能的不去用这个东西,汗一个先.
发现对这里还是有时会发生混乱. 教程里各位前辈通用说法是搞懂3大前置知识后就比较容易理解了,主要是下面3个:
函数、函数作用域、闭包
个人觉得简单的装饰器还是比较容易理解的,复杂的地方在于给装饰器加参数后,涉及嵌套层数问题,尤其层数超过3层时,逻辑很容易弄乱了,复杂程度是成倍上升,脑子不够用啊./(ㄒoㄒ)/~~
额,从头复习一下.函数跳过
装饰器本质还是一个函数,不过是一个复杂的嵌套函数,而且参数和返回值也可能是一个函数.这就比较难搞了点.
1. 函数作用域
def func(): age = 20
>>>print(age)NameError: name 'age' is not defined
直接报错,age是一个局部变量,只作用于函数内部,这里依据LEGB原则为L,变量搜索的优先级顺序依次是LEGB,
这里个人理解为程序已经在L级别的作用域中找到变量age,所以不会继续进行下一级的搜索.当函数执行完后,已经超出变量的作用域.这时只会在E级作用域中进行搜索,所以自然是找不到的.
L:local,局部作用域,函数中定义的变量
E:enclosing,嵌套的父级函数的局部作用域,即包含此函数的上级函数的局部作用域,但不是全局的
G:globa,全局变量,就是模块级别定义的变量
B:built-in,系统固定模块里面的变量,比如int,
def func(): class_num = 5 def inner(): age = 20 print(class_num,age) return inner
>>>func()<ipython-input-21-826639bd4f41> in func() 3 def inner(): 4 age = 20----> 5 print(class_num,age) 6 return innerNameError: name 'age' is not defined
这里用ipython3运行,可以看到print这一句出错,按上面LEGB原则,这是因为name作用域为inner内部的L级局部作用域,print语句这里则为上一级的E级,也就是嵌套的父级函数的局部作用域,所以报错.
改造一下函数:
def func(): class_num = 5 def inner(): age = 20 print(class_num,age) return inner
>>>a = func()>>>a()5 20
这时可以看到正常输出了class_num和age,按照LEGB的原则,变量搜索的优先级顺序依次是LEGB,也就是先从age所在的L级作用域搜索,这时找到age,L级没有class_num,继续搜索E级作用域,成功找到class_num,则print语句正常执行 .
综合上面,
这里个人理解为可以从当前作用域层级向上级查找搜索变量,但不能向下级搜索.
name = 'lili'def func(): class_num = 5 def inner(): age = 20 print('班级:{}班 姓名:{} 年龄{}'.format(class_num,name,age)) return inner
>>>a = func()>>>a()班级:5班 姓名:lili 年龄:20
可以看到,name是更上一层的G级,即全局变量,可以在内部调用.
如果想在函数内部修改全局变量,可以用global关键字
name = 'lili'def func(): class_num = 5 def inner(): global name age = 20 name = 'wang' print('班级:{}班 姓名:{} 年龄{}'.format(class_num,name,age)) return inner
>>>a = func()>>>a()班级:5班 姓名:wang 年龄:20
这时就将上层的全局变量修改了,同样,如果要修改父级局部作用域的局部变量class_num,可以用另一个关键字nonlocal
name = 'lili'def func(): class_num = 5 def inner(): nonlocal class_num age = 20 class_num = 8 print('班级:{}班 姓名:{} 年龄{}'.format(class_num,name,age)) return inner
>>>a = func()>>>a()班级:8班 姓名:lili 年龄:20
小结:
作用域共有4级,按优先级顺序依次是LEGB
L:local,局部作用域,函数中定义的变量
E:enclosing,嵌套的父级函数的局部作用域,即包含此函数的上级函数的局部作用域,但不是全局的
G:globa,全局变量,就是模块级别定义的变量
B:built-in,系统固定模块里面的变量,比如int,
可以从当前作用域层级向上级查找搜索变量,但不能向下级搜索.
调用的上级变量是不能直接进行赋值更改的,
要更改时必须用关键字 global 和 nonlocal
分别对应全局变量和父级局部作用域变量
- 装饰器学习笔记1:函数的作用域
- 装饰器学习笔记3:简单的函数装饰器
- Python函数的作用域、闭包、装饰器
- python 学习笔记---匿名函数 装饰器 偏函数
- python学习笔记,返回函数,匿名函数,装饰器
- python[变量作用域-函数-闭包-装饰器-生成器]
- python装饰器的学习笔记三
- python装饰器的学习笔记二
- python装饰器的学习笔记一
- 【Python学习笔记】函数式编程:装饰器
- python学习笔记 匿名函数和装饰器
- 《Fluent Python》学习笔记 chpter7函数装饰器
- 学习笔记(五)装饰器、迭代器、匿名函数
- python学习笔记-装饰器1
- Python学习笔记-1(变量、类型、函数、类、作用域)
- js学习笔记之函数作用域
- JavaScript 学习笔记 五 函数作用域
- JavaScript学习笔记(函数与作用域)
- tensorflow之seq2seq阅读笔记
- 算法之冒泡排序
- OpenCV笔记:填充边缘
- Android面试总结(持续更新修改)
- java代码转HTML(源码转换)
- 装饰器学习笔记1:函数的作用域
- win nginx thinkphp5 配置
- bzoj 1055: [HAOI2008]玩具取名 dp
- 编译交叉工具链powerpc-linux(干净的ubuntu)
- Ubuntu12.04 root用户登录设置
- python写文件时,仅一部分内容被写入文件,感觉被截断了
- pycharm IDE开发工具的使用技巧
- 登陆功能(三)
- cmake编译时遇到的问题解决