- 闭包:在嵌套函数中,变量即不在全局,也不在内层函数中,而且必须是内层函数对外层函数的变量的引用
- 开放封闭原则:对功能扩展是开放的,对源码的修改是封闭的...在不修改源码及调用方式的前提下,对功能进行额外地扩展就是开放封闭原则
- 装饰器
1. 标准版装饰器
def wrapper(func):
def inner(*args,**kwargs):
# 执行原函数之前的操作...
ret = func()
# 执行原函数之后的操作...
return ret
return inner
2. 标准版装饰器的例子 ---- 模拟博客园登录的装饰器
- 功能:已经登录的账号可以无障碍访问其他页面,没有登录的账号要访问其他页面时自动跳转到登录页面
login_status = {
'username':None,
'flag':False,
}
def auth(func):
def inner(*args,**kwargs):
if login_status['flag']:
ret = func(*args,**kwargs)
return ret
username = input('请输入用户名:').strip()
password = input('请输入密码:').strip()
if username == 'baoyuan' and password == 'bangbangde':
login_status['flag'] = True
ret = func(*args,**kwargs)
return ret
return inner
@auth
def diary():
print('欢迎访问日记页面')
def auth(x):
def auth1(func):
def inner(*args,**kwargs):
if dic_flag['flag']:
ret = func()
return ret
if x == 'wechat':
username = input('name')
password = input('pwd')
if username == 'asd' and password == '123':
ret = func()
return ret
if x == 'QQ':
username = input('name')
password = input('pwd')
if username == 'asd' and password == '123':
ret = func()
return ret
return inner
return auth1
@auth('wechat')
def jitter():
print('记录美好生活')
@auth('qq')
def pipefish():
print('期待你的内涵神评论')
3 最简单的装饰器
def auth(func):
def inner(*args, **kwargs):
ret = func(*args, **kwargs)
return ret
return inner
# @auth
def index():
print('Index')
print(index)
print(index.__name__)
这里print(index)运行有两种情况:
- 不加装饰器:<function index at 0x000001F7575F52F0>
- 加上装饰器:<function auth.
.inner at 0x000002266E7D5950>
print(index.__name__)
时也有两种情况:
- 不加装饰器:index
- 加上装饰器:inner
总结:加上装饰器之后,其实执行的是inner()函数,只不过这里的inner()函数没做任何操作而已。
4 @functools.wraps(func)
下面想要在加上装饰器之后print(index.__name__)
时,还是打印自己的函数名,具体操作如下:
import functools
def auth(func):
@functools.wraps(func)
def inner(*args, **kwargs):
ret = func(*args, **kwargs)
return ret
return inner
@auth
def index():
print('Index')
print(index.__name__)
注意:
- 这里
print(index.__name__)
的本质还是inner,但是加上@functools.wraps(func)装饰器后,inner()函数会带上index()函数上的一些内容,比如函数名。 - 相当于:把原函数的原信息封装到闭包中。