python装饰器

 1.请设计一个decorator,它可作用于任何函数上,并打印该函数的执行时间:

import functools
import time


def metric(fn):
    @functools.wraps(fn)
    def wrapper(*args, **kw):
        start = time.time()
        res = fn(*args, **kw)
        end = time.time()
        print('%s executed in %s ms' % (fn.__name__, end - start))
        return res
    return wrapper


# 测试
@metric
def fast(x, y):
    time.sleep(0.0012)
    return x + y


@metric
def slow(x, y, z):
    time.sleep(0.1234)
    return x * y * z


f = fast(11, 22)
s = slow(11, 22, 33)
if f != 33:
    print('测试失败!')
elif s != 7986:
    print('测试失败!')

2.请编写一个decorator,能在函数调用的前后打印出'begin call''end call'的日志。

import functools


def call(fn):
    @functools.wraps(fn)
    def wrapper(*args, **kw):
        print('begin call')
        res = fn(*args, **kw)
        print('end call')
        return res

    return wrapper

3.再思考一下能否写出一个@log的decorator,使它既支持:

@log
def f():
    pass

又支持:

@log('execute')
def f():
    pass

 评论看到的可以实现的:

import functools
from types import FunctionType, MethodType


def log(param):
    # 这是真正的装饰器,根据条件提供fn
    def pre_decorator(fn, text=None):
        @functools.wraps(fn)
        def wrapper(*args, **kw):
            print('func:%s log start...' % fn.__name__)

            # 如果text不为空,则打印text
            if text is not None:
                print("param: %s" % param)
            res = fn(*args, **kw)
            print('func:%s log end...' % fn.__name__)
            return res

        return wrapper

    # 如果param是可调用对象,直接返回装饰器
    if param is isinstance(param, (FunctionType, MethodType)) or hasattr(param, '__call__'):
        return pre_decorator(param)

    def decorator(func):
        return pre_decorator(func, param)

    return decorator


@log
def log_1():
    print('装饰器无参数测试.')


@log("qaaasd阿山东山东的山东撒到山东山东的撒到")
def log_2():
    print('装饰器有参数测试.')


log_1()
print('---------------------------------------')
log_2()

自己尝试但失败的:

import functools


def log(text):
    def decorator(fn):
        @functools.wraps(fn)
        def wrapper(*args, **kw):
            print('%s begin call, log text:%s' % (fn.__name__, text))
            res = fn(*args, **kw)
            print('%s end call, log text:%s' % (fn.__name__, text))
            return res

        return wrapper

    return decorator


@log()
def f1():
    print('run f1')


@log('execute')
def f2():
    print('run f2')


f2()
f1()

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值