python学习笔记(六)——函数的作用域和装饰器
目录
- 函数作用域
- global和nonlocal关键字
- 递归
- 闭包
- 装饰器
函数作用域
global和nonlocal关键字
思考:
def func():name = 'laowang'
print(name) # 能打印吗?func()
print(name) # 能打印吗?执行结果:
laowang
NameError: name 'name' is not defined 为什么没有被定义?
定义在函数内部的变量拥有一个局部作用域,定义在函数外的拥有全局作用域。
局部变量只能在其被声明的函数内部访问,而全局变量可以在整个程序范围内访问。
调用函数时,所有在函数内声明的变量名称都将被加入到作用域中
当内部作用域想修改外部作用域的变量时,就要用到global和nonlocal关键字了。
1、global
能够在函数里修改全局变量的值。
a = 100 # 全局变量
def func1():global a # 修改全局变量a = 200print(a)
func1()
print(a)执行结果:
200
200
2、nonlocal
让嵌套函数能够修改嵌套函数之外的值,就是用来修改嵌套作用域的变量的。
def func1():x = 100def func2():nonlocal xx += 100return xreturn func2()a = func1()
print(a)执行结果:
200
递归
在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。
实例 1:
# 递归
def fibonacci(a):if a == 0: # 简写 if a == 0 or a == 1: 与或非 逻辑运算符return 0elif a == 1:return 1else:return fibonacci(a-1) + fibonacci(a-2)a = fibonacci(20)
print(a)执行结果:
6765
实例 2:
# 递归乘积
def factorial(num): # feik toolr aoif num>1:result = num*factorial(num-1)else:result = 1return resulta = factorial(999) # 报错 998 不会
print(a)
思考: 下面的例子运行结果会怎么样?
def func()print('hello') func()
func()
该例子在打印多次hello后为什么会出现内存溢出?
因为该例子的函数没有出口。没有出口就会造成内存溢出。
内存溢出:内存不够,通常在运行大型软件或游戏时,软件或游戏所需要的内存远远超出了你主机内安装的内存所承受大小,就叫内存溢出。此时软件或游戏就运行不了,系统会提示内存溢出,有时候会自动关闭软件,重启电脑或者软件后释放掉一部分内存又可以正常运行该软件
闭包
闭包是函数里面嵌套函数,外层函数返回里层函数。
内部函数调用外部函数的的变量,外函数返回内函数的引用。
实例 1:
def func():def func1():return 'hello'return func1()
print(func())
执行结果:hello
实例 2:
def func(x):def func1():return 'hello'+xreturn func1
print(func('world')())
执行结果:hello world
实例 3:
def dome1():a = 100def dome2():return a + areturn dome2a = dome1()
print(a()) 200------------------------------------
li = []
for i in range(4):def func():return ili.append(func)for f in li:print(f()) 3 3 3 3 ------------------------------------
li = []
for i in range(4):def func(i):def func1():return ireturn func1li.append(func(i))for f in li:print(f()) 0 1 2 3
什么是引用?
在python中一切都是对象,包括整型数据1,函数,其实是对象。当我们进行a=1的时候,实际上在内存当中有一个地方存了值1,然后用a这个变量名存了1所在内存位置的引用。引用就好像c语言里的指针,大家可以把引用理解成地址。a只不过是一个变量名字,a里面存的是1这个数值所在的地址,就是a里面存了数值1的引用。相同的道理,当我们在python中定义一个函数def demo(): 的时候,
内存当中会开辟一些空间,存下这个函数的代码、内部的局部变量等等。这个demo只不过是一个变量名字,
它里面存了这个函数所在位置的引用而已。我们还可以进行x = demo, y = demo,
这样的操作就相当于,把demo里存的东西赋值给x和y,这样x 和y 都指向了demo函数所在的引用,
在这之后我们可以用x() 或者 y() 来调用我们自己创建的demo() ,
调用的实际上根本就是一个函数,x、y和demo三个变量名存了同一个函数的引用。
装饰器
装饰器用于拓展原来函数功能的一种函数,这个函数的特殊之处在于它的返回值也是一个函数。
装饰器的好处就在于不用更改原函数代码的前提下给函数增加新的功能。
作业:不影响之后写代码,会轻松很多,节省代码量
实例 1:
def func1(func3):def func2():print('----验证功能----')func3()return func2def func3():print('----登录功能----') # 登陆功能,不改变增加验证功能a = func1(func3) #一般调用写法
a()
改成装饰器后:
def func1(func3):def func2():print('----验证功能----')func3()return func2@func1 #相当于上面的a = func1(func3)
def func3():print('----登录功能----') # 登陆功能,不改变增加验证功能func3()
结果均为:
----验证功能----
----登录功能----
实例 2:(计算for循环所花费时间)
from datetime import datetime
def run_time(func): # 这是一个用来计算程序执行时间的装饰器def new_func():start_time = datetime.now()print('开始时间为:%s'%start_time)func()end_time = datetime.now()print('结束时间为:%s'%end_time)total_time = end_time - start_timeprint('总共花费时间为:%s'%total_time)return new_func@run_time
def count_sum2(): #从1加到10000count = 0for i in range(1,10001):count = count+ireturn countcount_sum2()
运行结果:
开始时间为:2021-03-31 00:36:48.318660
结束时间为:2021-03-31 00:36:48.319690
总共花费时间为:0:00:00.001030
python学习笔记(六)——函数的作用域和装饰器相关推荐
- Python学习笔记六——画小猪佩奇
目录 Python学习笔记六--画小猪佩奇 画布 画笔 属性设置 操纵命令 运动命令 画笔控制命令 全局控制命令 其他命令 Python学习笔记六--画小猪佩奇 使用Python的turtle库可以绘 ...
- Python学习笔记12_函数
Python学习笔记12_函数 文章目录 Python学习笔记12_函数 1.函数定义 2.函数调用 3.函数的参数 3.1.可更改对象和不可更改对象参数 3.2.必需参数(位置参数) 3.3.关键字 ...
- Python学习笔记:函数(Function)
Python学习笔记:函数(Function) 一.函数基本概念 函数是Python里组织与重用代码最重要的方法.一般来说,如果你期望多次重复相同或相似的代码,写一个可重用的函数可能是值得的.函数通过 ...
- Python学习笔记(六)
1. IO编程 1.1 文件读写 1.2 StringIO和BytesIO 1.3 操作文件和目录 1.4 序列化 2. 进程和线程 2.1 多进程 2.2 多线程 2.3 ThreadLocal 2 ...
- Python学习笔记---day12函数进阶
day12函数进阶 函数的嵌套 闭包 装饰器 上述内容均属于函数部分必备知识,以后开发时直接和间接都会使用,请务必理解(重在理解,不要去死记硬背). 1. 函数嵌套 Python中以函数为作用域,在作 ...
- 【python学习笔记】函数
一,函数的分类 #1.内置函数 为了方便我们的开发,针对一些简单的功能,python解释器已经为我们定义好了的函数即内置函数.对于内置函数,我们可以拿来就用而无需事先定义,如len(),sum(),m ...
- 小甲鱼python003答案_小甲鱼:Python学习笔记003_函数
>>> # 函数 >>> def myFirstFunction(params1,params2...): print("这是我的第一个函数!" ...
- Python学习笔记——一些函数
本文对应头歌上的Python练习:https://www.educoder.net/paths/pn7qklv9 基础知识1: input( )函数 input()函数从控制台获得用户输入,无论用户在 ...
- 趁着课余时间学点Python(九)函数的进阶 生成器 装饰器的理解
文章目录 前言 生成器 为什么使用 格式 嵌套函数 装饰器 使用场景 使用 结语 前言 相信大家已经对函数有了一定的理解了吧,那么来看看生成器和装饰器吧 生成器 按道理来说,生成器应该是和迭代器一起讲 ...
最新文章
- keras Classifier 分类
- linux 卸载 rtx,Ubuntu20.04系统卸载软件及清理系统垃圾缓存以及新力得
- poj1185炮兵阵地
- html判断表单是否为空,layui判断表单是否为空
- C++:线程操作之CRITICAL_SECTION用法的介绍和例子理解
- 如何id变动自动保存html软件,Wordpress折腾小记:彻底解决ID不连续的问题-自动保存、自动修订 | 地瓜哥博客网...
- SAP CRM WebClient UI点了产品主数据搜索结果超链接后的跳转调试
- kill掉占用端口程序
- [蓝桥杯][2014年第五届真题]兰顿蚂蚁(模拟)
- 果粉期待已久,iPhone 6s 或年底发布
- 中英文对照 —— 医学与医院
- 由一篇作文《一件有意义的事》展开的
- 机器学习面试要点总结
- BZOJ2286: [Sdoi2011]消耗战 虚树
- 批处理中 %~d0 cd %~dp0 的含义
- magento 修改订单状态为Completed
- 影响世界的100条管理励志名言
- vue和 element ui下载到本地后引入
- 山东艾思软件科技有限公司-公司介绍
- 查看当前目录和上一级目录的命令
热门文章
- 105. Leetcode 121. 买卖股票的最佳时机 (动态规划-股票交易)
- ML+DM顶会时间(2020)
- MATLAB可视化实战系列(四十二)-图像特征提取-使用低秩 SVD 进行图像压缩实例
- 理工科毕业设计献礼,MATLAB从入门到精通之矩阵是如何实现寻访与赋值的
- MATLAB实战系列(四)- LabVIEW初探
- 卷积神经网络(CNN)模型结构
- matlab 坐标修改gca及Matlab中输入上标、下标、希腊字母,特殊符号或字体
- MATLAB基本操作(二):数组中操作
- Python输出py文件模拟代码高亮
- python hmac_Python实现的HMacMD5加密算法示例