python学习笔记(六)

闭包: 能够访问其他函数内部变量的函数就叫做闭包,弱数据类型的语言特有的现象
闭包最大的特点就是将局部变量全局化,但导致了局部变量无法及时释放,常驻内存,内存的占有比较高,只是此时局部变量作用域比较小,代码整合时可以防止变量覆盖
闭包优化了变量,原来需要类对象完成的工作,闭包也可以完成

#这是一个闭包:inner函数能够访问outer函数内部变量a
#引用传递是将函数内存地址赋给变量,函数调用是将函数返回值赋给变量
def outer():
	a = 10
	print("这是外部函数")
	def inner():
		print(a)
		print("这是内部函数")
	return inner

#outer函数返回的是一个函数,所以此时a指向inner函数
a = outer()				#函数调用是将函数返回值(return inner)赋给变量
#print(a)				#<function outer.<locals>.inner at 0x000001918F667598>

#调用a函数,相当于调用inner函数
a()
#outer()()				#此时也可以调用inner函数

装饰器:就是在运行原来功能基础上,加上一些其它功能
装饰器功能:引入日志、函数执行时间统计、执行函数前预备处理、执行函数后清理功能、权限校验、异常处理、缓存
OCP原则(open close protocol):写代码要遵循开放封闭原则
设计模式的出现:golf提出了23种设计模式—装饰者设计模式

#闭包函数中的参数fn就是我们要装饰的对象,只需要加@logining就可以使用闭包函数logining()对原来的login()与reg()函数进行装饰
def logining(fn):
	def inner():
		print("正在加入日志")
		fn()
		print("日志已经加入")
	return inner		#此处返回inner函数,并且@logining已经将login函数替换为inner函数,下面调用login函数时返回的是inner函数
	
@logining				#执行@logining时logining函数中的fn就是login函数
def login():
	print("登录")
	
@logining
def reg():
	print("注册")

login()
reg()

1、被装饰的函数无参数

#装饰器没有打破OCP原则,而是将需要加入的功能正常的添加进去,可用于重构代码
#装饰器可以装饰多个函数
#被装饰函数无参数
def logining(fn):
	def inner():
		print("开始记录日志……")
		fn()
		print("日志记录完成……")
	return inner	
	
def check(fn):
	def inner():
		print("开始数据校验……")
		fn()
	return inner
	
@logining
@check			
def login():
	print("登录")
	
if __name__ == '__main__':
	login()

运行结果:
开始记录日志……
开始数据校验……
登录
日志记录完成……

2、被装饰的函数存在参数,则参数在装饰器内部的函数中传递

#被装饰函数有参数
def logining(fn):
	#如果被装饰的函数存在参数,则参数在装饰器内部的函数中传递
	def inner(username,password,*arg,**kwarg):
		print("开始记录日志……")
		fn(username,password,*arg,**kwarg)
		print("日志记录完成……")
	return inner	
	
def check(fn):
	def inner(username,password,*arg,**kwarg):
		print("开始数据校验……")
		fn(username,password,*arg,**kwarg)
	return inner
	
@logining
@check			
def login(username,password,*arg,**kwarg):
	print(username + "使用密码登录,密码是" + password)
	print("登录")
	
if __name__ == '__main__':
	UserName = "zhang"
	PassWord = "123"
	login(UserName,PassWord)

3、被装饰的函数存在返回值,则需要在内部函数调用原函数时返回

#如果被装饰的函数存在返回值,则需要在内部函数调用原函数时返回
def logining(fn):
	#如果被装饰的函数存在参数,则参数在装饰器内部的函数中传递
	def inner(username,password,*arg,**kwarg):
		print("开始记录日志……")
		f = fn(username,password,*arg,**kwarg)
		print("日志记录完成……")
		return f
	return inner	
	
def check(fn):
	def inner(username,password,*arg,**kwarg):
		print("开始数据校验……")
		return fn(username,password,*arg,**kwarg)
	return inner

@logining
@check			
def login(username,password,*arg,**kwarg):
	print(username + "使用密码登录,密码是" + password)
	print("登录")
	return True
	
if __name__ == '__main__':
	UserName = "zhang"
	PassWord = "123"
	login(UserName,PassWord)

偏函数:

#偏函数的使用
from functools import partial
def print_msg(msg,type = 1):
	if type == 1:
		for x in msg:
			print(x)
	elif type == 2:
		for k,v in msg.items():
			print(k,v)
	elif type == 3:
		for x in msg:
			print(x)
print_msg("you are dog?")				#type不写默认为1
print_msg({"k1":25,"k2":100,"k3":150},type = 2)
print_msg([1,2,3,4,5,6],type = 3)

#此时print_dict函数就是print_msg函数,但是print_dict的type值已经固定为2
print_dict = partial(print_msg,type = 2)
print_dict({"k1":25,"k2":100,"k3":150})	#等价于print_msg({"k1":25,"k2":100,"k3":150},type = 2)
print(print_dict)						#functools.partial(<function print_msg at 0x000002093A991E18>, type=2)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值