用最简单的例子了解装饰器
用最简单的例子了解装饰器
以下为作者个人理解。如不认同 ,欢迎留言。
1- 定义:
定义我也说不上来, 大家自行百度
2- 作用:
装饰器能在不大幅度修改原有代码的情况下添加功能
3- 推导步骤
1- 我这里有个 【查询函数】
def index():
print('这里有好多内部信息, 严禁外泄')
return 'ok'
2- 这时候我添加一个功能,只有指定的人才能看到这些数据, 下文称 【验证函数】
user_data = [{'username': '张三', 'password': 'zhangsan'}, {'username': '李四', 'password': 'lisi'}, {'username': '王五', 'password': 'wangwu'}]
def login(u_name, p_word):
data = {
'code': -1,
'msg': '验证未通过'
}
# 获取所有username和password
print(user_data)
# 方法一
for d in user_data:
if u_name in d['username']:
# 用户名存在
if p_word == d['password']:
data = {
'code': 1,
'msg': '用户 {} 登录成功'.format(u_name),
}
return data
else:
data = {
'code': -1,
'msg': '密码不正确'
}
return data
else:
data = {
'code': -1,
'msg': '用户不存在'
}
return data
3- 问题来了, 怎么把这个限制添加到查询功能上呢
第一步:拿到 【查询函数】 和 【验证函数】。 了解函数的调用
我们需要了解, 一个函数写完之后并不是直接执行, 而是需要调用的
def index():
data = {
'msg': '数据',
}
return data
写完之后, 其实并没有使用, 那我们如何使用呢。
def index():
data = {
'msg': '数据',
}
return data
index()
对的, 那就是调用。如果这个你能理解, 那你对装饰器就了解一半了
第二步:在 【验证函数】 中 调用 【查询函数】
我们写了验证功能, 只需要在验证成功的时候调用我们的函数,功能就添加上去了, 不信你跑一下
user_data = [{'username': '张三', 'password': 'zhangsan'}, {'username': '李四', 'password': 'lisi'}, {'username': '王五', 'password': 'wangwu'}]
def login(u_name, p_word):
data = {
'code': -1,
'msg': '验证未通过'
}
# 获取所有username和password
print(user_data)
# 方法一
for d in user_data:
if u_name in d['username']:
# 用户名存在
if p_word == d['password']:
index()
data = {
'code': 1,
'msg': '用户 {} 登录成功'.format(u_name),
}
return data
else:
data = {
'code': -1,
'msg': '密码不正确'
}
return data
else:
data = {
'code': -1,
'msg': '用户不存在'
}
return data
我们在验证成功的情况下调用 【查询函数】 功能就添加上去了
第三步:将验证功能封装起来
我不可能在一个项目中找出每个 【查询函数】 并把 验证的代码套在函数上, 我们试试封装起来。代码如下
def decorate_login(f):
def login(u_name, p_word):
data = {
'code': -1,
'msg': '验证未通过'
}
# 从数据库中获取所有username和password
user_data = get_sql_data()
print(user_data)
# 方法一
for d in user_data:
if u_name in d['username']:
# 用户名存在
if p_word == d['password']:
f()
data = {
'code': 1,
'msg': '用户 {} 登录成功'.format(u_name),
}
return data
else:
data = {
'code': -1,
'msg': '密码不正确'
}
return data
else:
data = {
'code': -1,
'msg': '用户不存在'
}
return data
return login
此时,我们只需调用decorate_login函数, 并将 【查询函数】 作为参数传进去就能做到在 【查询函数】 调用之前先验证。那又有一个问题了,我不可能在项目中找到每一个 【查询函数】 并把它替换成decorate_login函数。
第五步:骚操作, 语法糖
到达这一步, 装饰器已经基本完成, 只剩下调用问题。如何调用呢。 没错,就是传说中的骚操作,语法糖。
我们只需要在 【查询函数】前, 添加 @decorate_login 这行代码, 装饰器就完成了。完整代码如下:
import pymysql
# 连接并读取数据库
def get_sql_data():
# 连接数据库
conn = pymysql.connect(host='localhost',port=3306,db='self_demo',user='root',password='rock1204.')
# 创建一个游标
cursor = conn.cursor(pymysql.cursors.DictCursor)
# 编写sql语句
sql = 'select * from User'
# 执行sql语句
cursor.execute(sql)
# 查看sql
result = cursor.fetchall()
# 执行语句
try:
conn.commit()
except:
print('执行不成功')
# 关闭游标
cursor.close()
# 关闭连接
conn.close()
return result
# 登录验证 装饰器
def decorate_login(f):
def login(u_name, p_word):
data = {
'code': -1,
'msg': '验证未通过'
}
# 从数据库中获取所有username和password
user_data = get_sql_data()
print(user_data)
# 方法一
for d in user_data:
if u_name in d['username']:
# 用户名存在
if p_word == d['password']:
f()
data = {
'code': 1,
'msg': '用户 {} 登录成功'.format(u_name),
}
return data
else:
data = {
'code': -1,
'msg': '密码不正确'
}
return data
else:
data = {
'code': -1,
'msg': '用户不存在'
}
return data
return login
# 主要功能
@decorate_login
def index():
print('这里有好多内部信息')
return 'ok'
index('张三', 'zhangsan')
数据库需要自己调通(或者用列表代替,列表在上面代码), 我们发现, 调用【查询函数】也能实现验证功能。只是需要将参数传入,提供给【验证函数】使用。
4- 练习
以上是 【查询函数】外面套一层验证用户的【验证函数】。先需要对输入的用户名和密码长度进行限制,用户名长度不能超过6位, 密码不能超过20位。添加一个装饰器。
参考代码如下:
import pymysql
# 连接并读取数据库
def get_sql_data():
# 连接数据库
conn = pymysql.connect(host='localhost',port=3306,db='self_demo',user='root',password='rock1204.')
# 创建一个游标
cursor = conn.cursor(pymysql.cursors.DictCursor)
# 编写sql语句
sql = 'select * from User'
# 执行sql语句
cursor.execute(sql)
# 查看sql
result = cursor.fetchall()
# 执行语句
try:
conn.commit()
except:
print('执行不成功')
# 关闭游标
cursor.close()
# 关闭连接
conn.close()
return result
# 登录验证 装饰器
def decorate_login(f):
def login(u_name, p_word):
data = {
'code': -1,
'msg': '验证未通过'
}
# 从数据库中获取所有username和password
user_data = get_sql_data()
print(user_data)
# 方法一
for d in user_data:
if u_name in d['username']:
# 用户名存在
if p_word == d['password']:
f()
data = {
'code': 1,
'msg': '用户 {} 登录成功'.format(u_name),
}
return data
else:
data = {
'code': -1,
'msg': '密码不正确'
}
return data
else:
data = {
'code': -1,
'msg': '用户不存在'
}
return data
return login
# 主要功能
@decorate_login
def index():
print('这里有好多内部信息')
return 'ok'
index('张三', 'zhangsan')