python 练习4

一、
1.创建add_log装饰器,被装饰器的函数打印日志信息;
2.日至格式为:[字符串时间] 函数名:xxx, 运行时间:xxx,运行返回值
import functools
import time
def add_log(fun):
    @functools.wraps(fun)
    def wrapper(*args,**kwargs):
        start_time = time.time()
        res = fun(*args,**kwargs)
        end_time = time.time()
        print '[%s] 函数名:%s,运行时间:%.5f,运行的返回值结果%d' \
              %(time.ctime(),fun.__name__,end_time-start_time,res)
        return res
    return wrapper
@add_log
def add(x,y):
    time.sleep(1)
    return x+y
print add(1,2)

二、验证用户登陆的装饰器is_login
    1.如果用户登陆成功,则执行被装饰的函数
    2.如果用户登陆不成功,则执行登陆函数
import functools
login_users = ['admin', 'root']
def is_login(fun):
    @functools.wraps(fun)
    def wrapper(*args, **kwargs):
        if kwargs.get('name') in login_users:
            res = fun(*args, **kwargs)
            return res
        else:
            res = login()
            return res
    return wrapper
@is_login
def writeBlog(name):
    return '编写博客'
def login():
    return '登陆。。。'
print writeBlog(name='admin')
三、获取每个函数的执行时间
    1).函数执行之前计算时间
    2).函数执行之后计算时间
问题1:被装饰的函数有返回值的时候怎么办
问题2:如何保留被装饰函数的函数名和帮助文档信息
import time
import string
import random
import functools
# print string.ascii_letters
li = [random.choice(string.ascii_letters) for i in range(100)]

# print li
def timeit(fun):
    """这是一个装饰器材timeit"""
    @functools.wraps(fun)
    def wrapper(*arges, **kwargs):  # 接收可变参数和关键字参数
        """这是一个wrpper函数"""
        # args:元组 kwargs:字典
        # 函数执行之前
        start_time = time.time()
        # 执行函数
        res = fun(*arges, **kwargs) #fun_list(50000)
        # 函数执行之后
        end_time = time.time()
        print '运行时间为:%.6f' % (end_time - start_time)
        return res
    return wrapper
四、用户登陆验证的装饰器is_login
       1). 如果用户登陆成功, 则执行被装饰的函数;
       2). 如果用户登陆不成功, 则执行登陆函数
需求: 判断登陆用户是否未管理员is_admin(此处管理员只有一个为:admin用户)
      1).如果用户为管理员, 则执行被装饰的函数;
      2).如果用户不是管理员, 则报错;
import functools
login_users = ['admin', 'root']
def is_admin(fun):
    @functools.wraps(fun)
    def wrapper(*args,**kwargs):
        if kwargs.get('name') == 'admin':
            res = fun(*args,**kwargs)
            return res
        else:
            return 'Error:您没有权限访问该网站'
    return wrapper

def is_login(fun):
    @functools.wraps(fun)
    def wrapper(*args, **kwargs):
        if kwargs.get('name') in login_users:
            res = fun(*args, **kwargs)
            return res
        else:
            res = login()
            return res
    return wrapper
@is_admin               
@is_login               
def login(name):        
    return '符合权限'       
def no_login():         
    return 'sorry'      
print login(name='admin')

五、编写装饰器required_ints, 条件如下:
     1). 确保函数接收到的每一个参数都是整数;
     2). 如果参数不是整形数, 打印 TypeError:参数必须为整形
def required_ints(sun):                    
    def a(*args,**kwargs):                 
        for i in args:                     
            if isinstance (i,int):         
                pass                       
            else:                          
                print 'TypeError:参数必须为整形'  
                break                      
        else:                              
            res =sun(*args,**kwargs)       
            return res                     
    return a                               
@required_ints                             
def ooo(n,g,h,j,k):                        
    return n+g+h+j+k                       
                                           
print ooo(2,1,4,5,7.8,) 
                   
六、带有参数的装饰器
def log(kind):                                                                
    def add_log(sun):                                                         
        def a(*args,**kwargs):                                                
            start_time = time.time()                                          
            res =sun(*args,**kwargs)                                          
            end_time=time.time()                                              
            print   '<%s> [%s] 函数名:%s,运行时间:%.5f,运行的返回值结果%d' \                 
                      %(kind,time.ctime(),sun.__name__,end_time-start_time,res)
            return res                                                        
        return a                                                              
    return add_log                                                            
# log('debug')                                                                
# add = add_log(add)                                                          
                                                                              
                                                                              
@log('debug')
def add(w,e):
    return w+e
print add(3,6)
七、升级版(有参数的装饰器)
编写装饰器required_types, 条件如下:
 1). 当装饰器为@required_types(int,float)确保函数接收到的每一个参数都是int或者float类型;
 2). 当装饰器为@required_types(list)确保函数接收到的每一个参数都是list类型;
 3). 当装饰器为@required_types(str,int)确保函数接收到的每一个参数都是str或者int类型;
 4). 如果参数不满足条件, 打印 TypeError:参数必须为xxxx类型;
 def log(*kind):
    def add_log(sun):                                 
        def a(*args,**kwargs):                        
            for i in args:                            
                if isinstance(i,kind):                
                    pass                              
                else:                                 
                    print 'typeError:参数必须为%s类型' %kind 
                    break                             
            else:                                     
                res = sun(*args,**kwargs)             
                return res                            
        return a                                      
    return add_log                                    
@log(str)                                             
def sum(a,b):                                         
    return a+b                                        
print sum(55,93)  
                                    

猜你喜欢

转载自www.cnblogs.com/zhengyipengyou/p/9642524.html