Python——day12 nonlcoal关键字、装饰器(开放封闭原则、函数被装饰、最终写法)
一、nonlocal关键字
1、作用:将L与E(E中的名字需要提前定义)的名字统一
2、应用场景:如果想在被嵌套的函数中修改外部函数变量(名字)的值
def outer():
num=10
print(num) # 输出结果为10
def inner():
nonlocal num
num=20
print(num) #输出级结果为20
inner()
print(num) # 输出结果为20
def outer():
num= # 必要写 是用于L与E的名字统一
def inner():
# 如果想被嵌套的函数中修改外部函数变量(名字)的值
nonlocal num # 将L与E(E中的名字需提前定义好)的名字统一
num=
print(num) # 输出结果为10
inner()
print(num ) # 定义了nonlocal就是局部统一,输出结果为10
outer()
# print(num)# 属于全局,不能看到其值
二、开放封闭原则
1、原则: 不能修改被装饰对象(函数)的源代码——封闭
不能更改被修饰对象(函数)的调用方式,且能达到增加功能的效果——开放
.0版本
def fn():
print('fn run ')
fn() 版本2.
def fn2():
print('fn run 0')
print('fn run1')
print('fn run2') 修改了源代码,没有更改调用方式,对外调用方式还是原来的,
def fn():
print('fn run0')
print('fn run ')
print('fn run2') 更改了调用方式,没有修改原功能代码块
def wrap(fn):
print('fn run0')
fn()
print('fn run2')
wrap(fn)
三、装饰器
1、定义:就是闭包(闭包的一个应用场景)
把要装饰的函数作为外部函数的参数通过闭包操作返回一个替代版函数1 2、优点:丰富了原有函数的功能
提高了程序的可拓展性 把要被装饰的函数作为外层函数的参数通过闭包操作后返回一个替代版函数
被装饰的函数:fn
外层函数:outer(func)、outer(fn)==》func=fn
替代版函数;return inner:原有功能加新功能
def fn():
print('原有功能') # 装饰器
def outer(tag):
def inner():
tag()
print('新增功能')
return inner
fn=outer(fn)
fn()
案例 花瓶
def vase():
print('插花')
vase() 增加一个绘画后观赏功能
def wrap(fn):
vase()
print('插花')
print('绘画:进行观赏')
wrap(vase) 虽然满足了开放封闭原则,但出现了函数调用死循环 def fn():
vase()
print('绘画:进行观赏')
vase=fn()
vase() 了解:满足开放fengbiyuanze,且可以达到装饰器的作用:拓展功能
tag=vase # 暴露在全局:
def fn():
tag()
print('绘画:进行观赏')
vase=fn
vase() 满足开放封闭原则(完美方法)
方式一
def wrap (tag):
tag=vase
def fn():
tag()
print('绘画:进行观赏')
return fn # 拓展功能后的vase
vase =wrap() # 相当于vase=fn
vase() 方式二、这个函数嵌套结构就是装饰器
def wrap (tag):
def fn():
tag() # 指原有的vase
print('绘画:进行观赏')
return fn # 拓展功能后的vase
vase =wrap(vase) # 将拓展功能后的函数重新赋值给vase
vase() # 功能拓展了,且调用方式不变
四、装饰器的简化语法
ef outer(f):
def inner():
f()
print("新增功能1")
return inner def wrap(f):
def inner():
f()
print("新增功能2")
return inner @wrap # 被装饰的顺序决定了新增功能的执行顺序
@outer # <==> fn = outer(fn): inner
def fn():
print("原有功能")
案例: def outer (fn):
def inner():
fn()
print('绘画:进行观赏')
return inner def wrse (fn):
def inner():
fn()
print('摆放功能')
return inner @语法糖|笑笑语法 @wrse
@outer #等于这个功能<==>vase =outer(vase)
def vase():
print('插花')
vase() 总结:一个函数可以被任意一个相关装饰器装饰,也可以被任意几个装饰器装饰
注:装饰的顺序会影响新增功能的执行顺序
五、有参有返的函数被修饰
def check_usr(fn):# fn,login,inner:不同状态下的login,所以参数是统一的
def inner(usr,pwd):
# 在原功能上添加新功能
if not(len(usr)>=3and usr.isalpha()):
print('账号验证失败')
return False
# 原有功能
result=fn(usr,pwd)
# 在原功能下添加新功能
#。。。。。()没有添加则用句号省略了
return result
return inner @check_usr
def login(usr,pwd):
if usr=='abc'and pwd=='123abc':
print('登录成功')
return True
print('登录失败')
return False 总结:1、login有参数,所以inner与fn都有相同参数
2、login有返回值,所以inner与fn都有返回值 inner(usr, pwd):
res = fn(usr, pwd) # 原login的返回值
return res login = check_usr(login) = inner res = login('abc', '123qwe') # inner的返回值
案例: 增加一个账号处理功能:3位以上英文字符或汉字 def check_usr(fn):
def inner(usr,pwd):
if not (len(usr)>=3 and usr.isalpha()):
print('账号验证失败')
return False
result=fn(usr,pwd) #login
return result
return inner 增加一个密码处理功能:6位以上英文和数字
def check_pwd(fn):
def inner(usr,pwd):
if not (len(pwd)>=6 and pwd.isalnum()):
print('密码验证失败')
return False
return fn(usr,pwd) #result=fn(usr,pwd) return result
return inner 登录功能
@check_usr # login=check_usr(login)=inner
def login(usr,pwd):
if usr=='abc' and pwd=='123abc':
print('登录成功')
print('登录失败')
return False res=login('abc','123abc') # inner 用户名和密码正确输出验证成功
print(res)
六、装饰器的最终写法
# 装饰器的最终写法
def wrap (fn):
def inner(*args,**kwargs):
print('前增功能')
result =fn(*args,**kwargs)
print('后增功能')
return result
return inner @wrap
def fn1():
print('fn1的原有功能')
@wrap
def fn2(a,b): # 有参数无值
print('fn2的原有功能') @wrap
def fn3():# 有返回值无参数
print('fn2的原有功能')
return True
@wrap
def fn4(a,*,c): #有参数有返回值
print('fn2的原有功能')
return True fn1()
fn2(10,20)
fn3()
fn4(10,c=20) 案例:
增加一个账号处理功能:3位及以上英文字符或汉字
def check_usr(fn):
def inner(usr,pwd):
if not(len(usr)>=3 and usr.isalpha()):
print('账号验证失败')
return False
result=fn(usr,pwd) #login
return result
return inner 登录功能
@check_usr
def login(usr,pwd):
if usr=='abc'and pwd=='123abc':
print('登录成功')
return True
print('登录失败')
return False res=login('abc','123abc') #inner 账号密码正确打印成功
print(res)
带参装饰器 def outer(input_color):
def wrap(fn):
if input_color=='red':
info='\033[36;41m new action\33[0m'
else:
info='yellow:new action'
def inner(*args,**kwargs):
pass
result=fn(*args,**kwargs)
print(info)
return result
return inner
return wrap #outer(color)=>>wrap color=input('color:') def func():
print('func run')
func()
七、登录认证案例
is_login=False #登录状态
def login():
usr=input('usr:')
if not(len(usr)>=3 and usr.isalpha()):
print('账号验证失败')
return False
pwd=input('ped:')
if usr=='abc'and pwd=='123abc':
print('登录成功')
is_login=True
else:
print('登录失败')
is_login=False 完成一个登录状态校验的装饰器 def check_login(fn):
def inner(*args,**kwargs):
# 查看个人主页或销售功能前:如果没有登录需要先登录,繁殖可以进入其功能
if is_login!=True:
print('你未登录')
login()
# 查看个人主页或销售
result=fn(*args,**kwargs)
return result 查看个人主页功能
@check_login
def home():
print('个人主页') 销售功能
@check_login
def sell():
print('可以销售')
home()
Python——day12 nonlcoal关键字、装饰器(开放封闭原则、函数被装饰、最终写法)的更多相关文章
- 【Python入门学习】闭包&装饰器&开放封闭原则
1. 介绍闭包 闭包:如果在一个内部函数里,对在外部作用域的变量(不是全局作用域)进行引用,那边内部函数被称为闭包(closure) 例如:如果在一个内部函数里:func2()就是内部函数, 对在外部 ...
- python 装饰器 对类和函数的装饰
#装饰器:对类或者函数进行功能的扩展 很多需要缩进的没有进行缩进'''#第一步:基本函数def laxi(): print('拉屎')#调用函数laxi()laxi() print('======= ...
- Day 12 开放封闭原则,装饰器初识
nonlocal关键字 # 作用:将 L 与 E(E中的名字需要提前定义) 的名字统一# 应用场景:如果想在被嵌套的函数中修改外部函数变量(名字)的值# 案例:def outer(): n ...
- 装饰器和"开放-封闭"原则
装饰器和"开放-封闭"原则 "开放-封闭"原则 软件开发中的"开放-封闭"原则,它规定已经实现的功能代码不应该被修改,但可以被扩展,即: 封 ...
- 【Python 函数对象 命名空间与作用域 闭包函数 装饰器 迭代器 内置函数】
一.函数对象 函数(Function)作为程序语言中不可或缺的一部分,但函数作为第一类对象(First-Class Object)却是 Python 函数的一大特性. 那到底什么是第一类对象(Firs ...
- Python装饰器、内置函数之金兰契友
装饰器:装饰器的实质就是一个闭包,而闭包又是嵌套函数的一种.所以也可以理解装饰器是一种特殊的函数.因为程序一般都遵守开放封闭原则,软件在设计初期不可能把所有情况都想到,所以一般软件都支持功能上的扩展, ...
- Python学习之路基础篇--11-12Python基础,函数的装饰器
对于装饰器来说,就是在不改变函数的调用的情况下,对函数的前后增加了些许功能,这完全符合函数的 开放封闭 原则.装饰器的本质 其实就是一个闭包函数. 这是一个装饰器的步骤图 ret = func(*ar ...
- python函数知识七 闭包、装饰器一(入门)、装饰器二(进阶)
21.闭包 闭包:在嵌套函数内,使用非全局变量(且不使用本层变量) 闭包的作用:1.保证数据的安全性(纯洁度).2.装饰器使用 .__closure__判断是否是闭包 def func(): a = ...
- python 装饰器(四):装饰器基础(三)叠放装饰器,参数化装饰器
叠放装饰器 示例 7-19 演示了叠放装饰器的方式:@lru_cache 应用到 @clock 装饰fibonacci 得到的结果上.在示例 7-21 中,模块中最后一个函数应用了两个 @htmliz ...
随机推荐
- macOS10.13.2配置TensorFlow
安装Python python3是通过Homebrew安装的,默认安装的是3.7.0版本,但TensorFlow目前只能在3.4,3.5,3.6上安装,因此首先需要安装3.6版本的python. 首先 ...
- python接口自动化1
组织架构: 包括配置文件,反射.文件路径.Excel操作.测试报告生成 case.config [MODE] file_name=case_data.xlsx mode={"register ...
- Linux NFS服务器的安装与配置方法(图文详解)
这篇文章主要介绍了Linux NFS服务器的安装与配置方法(图文详解),需要的朋友可以参考下(http://xb.xcjl0834.com) 一.NFS服务简介 NFS 是Network File S ...
- 二、OpenStack—keystone组件介绍与安装
一.Keystone介绍 keystone 是OpenStack的组件之一,用于为OpenStack家族中的其它组件成员提供统一的认证服务,包括身份验证.令牌的发放和校验.服务列表.用户权限的定义等等 ...
- ios6和ios5横竖屏切换
记录于2013/8/5 在切换横竖屏的时候调用到的一些委托方法: #pragma mark - UIApplicationDelegate //写在Appdelegate中,在具体的某一视图控制器 ...
- tensorflow 使用 3 模型学习
模型学习 import tensorflow as tf import numpy as np # 生成 100 个随机的点 x_data = np.random.rand( 100 ) y_data ...
- TortoiseGit的ssh key和Git的ssh key
情景模拟: 你使用Git+TortoiseGit对项目进行版本控制,本地库(自己电脑建立的.git)与远程库(如GitLab上建立)通信需要使用ssh验证,你用git生成公钥并保存到了Gitlab上, ...
- 开发中少不了的Fun -- 微信开发IOS端alert/confirm提示信息,去除网址(URL)的方法
在微信公众号开发的时候在使用[alert/confirm]弹出提示或者警告信息的时候,[alert/confirm]会将该公众号的网址显示出来,这样很不美观.所以很多时候我们会选择去除那个网址提示内容 ...
- Makefile = ?= := 区别 $@,$^,$<
= 是最基本的赋值:= 是覆盖之前的值?= 是如果没有被赋值过就赋予等号后面的值+= 是添加等号后面的值 1.“=” make会将整个makefile展开后,再决定变量的值.也就是说,变量的值将会是整 ...
- sql server创建登录出发器后导致登录失败--解决方案
1.选择sql server配置管理器---sql server服务--右键属性--启动参数--添加-f.-m两个参数并重启sql server服务 2.重新启动sql server以windos身份 ...