一、函數認證
編寫裝飾器,爲多個函數加上認證的功能(用戶的賬號密碼來源於文件)。要求:登錄成功一次,後續的函數都無需再輸入用戶名和密碼
db = 'a.txt'
login_status = {'status': False}
def auth(auth_type='file'):
def auth2(func):
def wrapper(*args, **kwargs):
if login_status['status']:
return func(*args, **kwargs)
if auth_type == 'file':
with open(db, encoding='utf-8') as f:
dic = eval(f.read())
name = input('username: ').strip()
password = input('password: ').strip()
if name == dic['name'] and password == dic['password']:
login_status['status'] = True
res = func(*args, **kwargs)
return res
else:
print('username or password error')
elif auth_type == 'sql':
pass
else:
pass
return wrapper
return auth2
@auth()
def index():
print('index')
@auth(auth_type='file')
def home(name):
print('welcome %s to home' % name)
index()
home('albert')
二、超時重登
編寫裝飾器,爲多個函數加上認證功能,要求登錄成功一次,在超時時間內無需重複登錄,超過了超時時間,則必須重新登錄
寫法一
import time
import random
user_data = {
'user': None,
'login': False,
'now_time': time.time()
}
db_username = 'albert'
db_password = '123'
def auth(func):
def wrapper(*args, **kwargs):
passed_time = time.time() - user_data['now_time']
if user_data['user'] and passed_time < 3:
return func(*args, **kwargs)
else:
while True:
username = input('input your username>>:').strip()
password = input('input your password>>:').strip()
if username == db_username and password == db_password:
print('login successfully')
user_data['user'] = username
user_data['login'] = True
user_data['now_time'] = time.time()
return func(*args, **kwargs)
else:
print('username or password is invalid')
return wrapper
@auth
def index():
print('This is index page')
@auth
def home(name):
print('Welcome %s to home page' % name)
index()
time.sleep(random.randint(2, 4)) # create 2-4 random number
home('albert')
寫法二
# 裝飾器,認證功能,用戶密碼來源於文件,設定超時時間,超時需重新登錄
import time
current_user = {
'user': None,
'login_time':None,
'timeout':10
}
def timer(func):
def wrapper(*args, **kwargs):
start_time = float(current_user['login_time'])
res = func(*args, **kwargs)
stop_time = time.time()
t = stop_time - start_time
print('已登錄時間%.3ss' %t)
funcs_dict = {
'1':welcome,
'2':shopping
}
while t < current_user['timeout']:
choice = input('選擇執行函數:')
funcs_dict[choice]()
else:
current_user['user'] = None
auth(func)
return res
return wrapper
def auth(func):
def wrapper(*args, **kwargs):
if current_user['user']:
print('login already')
return func(*args,**kwargs)
name = input('username>>:').strip()
pwd = input('pwd>>:').strip()
with open('users.txt') as f:
for line in f:
if line.startswith(name):
info = line.strip().split('|')
if name == info[0] and pwd == info[1]:
print('login succeed')
current_user['user'] = name
current_user['login_time'] = time.time()
res = func(*args, **kwargs)
return res
else:
print('error')
break
return wrapper
@auth
@timer
def welcome():
print('welcome')
@auth
@timer
def shopping():
print('shopping')
welcome()
shopping()
三、日誌
編寫日誌裝飾器,實現功能:一旦某函數執行,則將函數執行時間寫入到日誌文件中,日誌文件路徑可以指定。
import time
def add_log(file):
def wrapper(func):
def inner(*args, **kwargs):
with open(file, 'a', encoding='utf-8') as f:
f.write('[%s]:[%s]\n' % (func.__name__, time.strftime('%Y-%m-%d %X')))
return func(*args, **kwargs)
return inner
return wrapper
@add_log('db1.txt')
def index():
print('This is index page')
@add_log('db2.txt')
def home(name):
print('Welcome %s to home page' % name)
index()
home('albert')