day-13装饰器
函数的嵌套定义
概念:在一个函数的内部定义另一个函数
为什么要有函数的嵌套定义:
1)函数fn2想直接使用fn1函数的局部变量,可以将fn2直接定义到fn1的内部,这样fn2就可以直接访问fn1的变量
2)函数fn2名字就变成fn1的局部变量了,正常只能在fn1中使用,想在外部使用,可以讲fn2函数对象作为fn1函数的返回值
3)在外部也用同名的变量fn2来接收fn1函数的执行结果(fn1函数的返回值),那么fn2也就是可以在外部被调用
global关键字
作用:将局部的变量提升为全局变量
1.全局没有同名变量,直接提升局部变量为全局变量
2.有同名全局变量,就是统一全局与局部的同名变量
-- 如果局部想改变全局变量的值(发生地址的变化),可以用global声明该变量
# num = 888
def fn1():
global num
# print(num)
# 没有global修饰,num就是自己局部的变量
# 有global修饰,num就是全局的num,全局中只能出现一个num,如果出现了值的改变,大家一起变
num = 666
def fn2():
print(num) #
fn1()
fn2()
nonlocal关键字
作用:将局部的变量提升为嵌套局部变量
1.必须有同名嵌套局部变量,就是统一嵌套局部与局部的同名变量
-- 如果局部想改变嵌套局部变量的值(发生地址的变化),可以用nonlocal声明该变量
def outer():
num = 888
def inner():
nonlocal num
num = 666
print(num) #
inner()
print(num) #
outer()
开放封闭原则
开放封闭原则:在不修改源代码与调用方式的情况下为函数添加新功能 *****
开放:有些事,你可以干 - 拓展功能
封闭:有些事,你干不了 - 两个原则
1.不能修改源代码 - 1.无权修改 2.功能不特有 3.修改的位置多个,需要一一修改
2.不能修改原函数的调用方式 - 修改调用方式的弊端,原项目的所有函数调用都要修改
装饰器
装饰器:满足开放封闭原则的一个闭包应用
# @outer语法来调用outer,规定传入被装饰的函数对象,所以参数固定为一个,接受被装饰的函数对象
def outer(func):
# 不能确定被装饰的函数的参数:来者不拒,用可边长来接受
def inner(*args, **kwargs):
pass # 新功能位
res = func(*args, **kwargs) # 解压带给原功能
pass # 新功能位
return res
return inner # 使用装饰器(outer),得到新功能(inner) # 用被装饰的函数名去接受装饰器的执行结果,调用装饰器时传入被装饰的函数对象
@outer # fn = outer(fn) = inner
def fn(): pass # 表面感觉调用的是原函数,本质调用的是闭包(inner),使用fn调用和fn定义及inner需要参数统一
fn()
一个函数被多次装饰
def outer(func):
def inner(*args, **kwargs):
res = func(*args, **kwargs)
return res
return inner def check_user(func):
def inner(*args, **kwargs):
# 账号的验证功能
user = args[0] # type: str
if not (user.isalpha() and len(user) >= 3):
print('账号不合法')
return False res = func(*args, **kwargs)
return res
return inner def check_pwd(func):
def inner(*args, **kwargs):
pwd = args[1]
if len(pwd) < 3:
print('密码不合法')
return False res = func(*args, **kwargs)
return res
return inner def format_return(func):
def inner(*args, **kwargs):
res = func(*args, **kwargs)
if res:
return '登录成功'
return '登录失败'
return inner # 登录的原功能 @format_return
@check_user
@check_pwd
def login(user, pwd):
if user == 'owen' and pwd == '':
return True
return False user = input('user: ')
pwd = input('pwd: ')
res = login(user, pwd)
print(res)
执行过程:调用login => 进入第一个装饰器(format_return)的inner => 进入第二个装饰器(check_user)的inner => 进入第三个装饰器(check_pwd)的inner => 开始返回,从第三个返回到第二个再返回到第一个,最后返回到外界调用的位置
day-13装饰器的更多相关文章
- Python基础:13装饰器
装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的应用有插入日志.性能测试.事务处理等.装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同 ...
- Python Day 13 装饰器
阅读目录 内容回顾 函数嵌套的定义 global.nonlocal关键字 闭包及闭包的运用场景 开放封闭原则 装饰器 一个函数被多次装饰 ##内容回顾 1.函数对象:函数名 => 存放的是函 ...
- day 13 装饰器
装饰器基础 装饰器的目的是为了给被装饰 对象,增加新功能,或者说增加某种能力 在程序中工具就是函数 如此一来,装饰器指的就是一个函数,被装饰着也是一个函数 总结;装饰器就是用一个函数去拓展另外一个已存 ...
- python 基础之第十天(闭包,装饰器,生成器,tarfile与hashlib模块使用)
局部变量与全局变量 局部变量:在函数里面定义的,只有当函数活动时才生效 全局变量:不在函数里面的 In [1]: x=10 In [2]: def bar(): ...: x=20 ...: prin ...
- 13、python中的函数(闭包与装饰器)
一.嵌套函数 函数的内部又再定义另一个函数,这个函数就叫嵌套函数,里面含函数就叫内部函数. 示例: 二.返回函数 函数可以接收函数对象作为参数,同理函数也能返回一个函数对象作为返回值. 示例: 返回函 ...
- 13.Python略有小成(装饰器,递归函数)
Python(装饰器,递归函数) 一.开放封闭原则 软件面世时,不可能把所有的功能都设计好,再未来的一两年功能会陆续上线,定期更新迭代,软件之前所用的源代码,函数里面的代码以及函数的调用方式一般不 ...
- 【0812 | Day 13】闭包函数/装饰器/迭代器
目录 闭包函数 无参装饰器 有参装饰器 迭代器 闭包函数 一.什么是闭包? 闭包指的是:函数内部函数对外部作用域而非全局作用域的引用. def outter(): x = 1 def inner(): ...
- 『德不孤』Pytest框架 — 13、Pytest中Fixture装饰器(三)
目录 9.ids参数说明 10.name参数说明 11.scope参数说明 (1)scope="function" (2)scope="class" (3)sc ...
- python 函数之装饰器,迭代器,生成器
装饰器 了解一点:写代码要遵循开发封闭原则,虽然这个原则是面向对象开发,但也适用于函数式编程,简单的来说,就是已经实现的功能代码不允许被修改但 可以被扩展即: 封闭:已实现功能的代码块 开发:对扩张开 ...
- Python之路第一课Day4--随堂笔记(迭代生成装饰器)
上节回顾: 1.集合 a.关系测试 b.去重 2.文件操作及编码 3.函数 4.局部变量和全局变量 上节回顾 本节课内容: 1.迭代器生成器 2.装饰器 3.json pickle数据序列化 4.软件 ...
随机推荐
- [SCOI2003]字符串折叠
一道蛮好玩的区间DP...其实只要做好check...然后统计答案就好了...QAQ... 呆码: #include<iostream> #include<cstdio> #i ...
- 关于MySQL什么时候使用索引问题以及什么情况下应不建或少建索引
一,什么情况下使用索引1. 表的主关键字 自动建立唯一索引 2. 表的字段唯一约束 ORACLE利用索引来保证数据的完整性 3. 直接条件查询的字段 在SQL中用于条件约束的字段 如zl_yhjbqk ...
- mysql命令行下创建数据库,创建表,插入数据,查询数据
1.创建数据库 mysql> create DATABASE booktik -> ;Query OK, 1 row affected (0.02 sec) 2.创建表 mysql> ...
- php的array数组 -------方法foreach循环时候,利用数组里值的引用地址(& )从而改变数组里的值
/* * 把每个数组值后面都加个SQL然后返回数组 * foreach循环时候,直接用引用(&)的方式就能改变之前的数组 */public function array_foreach(){ ...
- 分页(pagination)样式表
ul { list-style: none; padding:; margin:; } .pagination{ display:inline-block; padding-left:; border ...
- 浏览器兼容性汇总--CSS篇
目录 CSS篇 1. cursor:hand VS cursor:pointer 2. innerText在IE中能正常工作,但在FireFox中却不行 3. ...
- Holer实现手机APP应用外网访问本地WEB应用
手机APP应用公网访问内网WEB应用 本地安装了WEB服务端,手机APP应用只能在局域网内访问本地WEB,怎样使手机APP应用从公网也能访问本地WEB? 本文将介绍使用holer实现的具体步骤. 1. ...
- CodeBlocks无法调试的解决方法
闲话: 万万没想到我也会写这个东西.一开始软件工程课的时候老师要求我们写博客园,一直都是被动地在写博客.刚刚在重温C语言的时候发现的各种各样问题觉得还是写下来比较好,一旦以后自己又忘了呢……(摊手 顺 ...
- 团队合作one
一.项目介绍 为生活在长大的学生提供方快捷的生活服务,通过帖子发现自己志同道合的朋友,记录自己在长大点滴.本项目的意义在于锻炼团队的scrum能力,加强团队合作能力.确定本项目采用的技术方向:本项目整 ...
- 用PHP判断是否闰年(正则匹配法)
<?php /** * PHP判断是否闰年 */ $year="2004-02-29"; $pattern='/(([0-9]{3}[1-9]|[0-9]{2}[1-9][0 ...