装饰器1

装饰器的本质:一个闭包函数

装饰器的功能:在不修改原函数及其调用方式的情况下对原函数功能进行扩展

开放封闭原则

程序实体应该是可扩展,而不可修改的。也就是说,对扩展是开放的,而对修改是封闭的。

而装饰器就很好的适应这个原则

装饰器运用到的知识

函数中嵌套函数;函数返回一个函数;将函数作为参数传给另⼀个函数。

def sayhi():
    print('hi')
def saybefore(func):
    print('who is he?')
    return func
#saybefore就是一个装饰器
装饰器的实现
def decorator(F):
# Process function F
return F
@decorator
def func(): ... # func = decorator(func)

所以上面等同于

def saybefore(func):
    print('who is he?')
    return func
@saybefore
def sayhi():
    print('hi')
# 运行发现saybefore被调用了!并返回了一个函数。

现在想要每次“说的内容不一样”:sayhi中可以打印其他内容

def saybefore(func):
    print('who is he?')
    return func
@saybefore
def sayhi(arg):
    print(c)
sayhi('Hellow')
# -----------------------------
def saybefore(func):
    def inner(arg):
        print('who is he')
        return func(arg)
    return inner
装饰器的使用

日志

在系统中被调用(执行)的函数(程序),有很多种。
要求:打印被调用的函数名,并返回函数的结果,
试想一下不使用装饰器如何编写代码:每个函数除实现原有功能中都要添加返回自身函数名的代码
而有时又不希望打印函数名。。。

#使用装饰器,只要事先写好好需要扩展的功能,对需要扩展功能的函数修饰就可以了
from functools import wraps
def logit(func):
    @wraps(func)
    def with_logging(*args, **kwargs):
        print(func.__name__ + " was called")
        return func(*args, **kwargs)
    return with_logging
@logit       
def addition_func(x):
    '''Do some math'''
    return x + x
result = addition_func(4)
装饰器的wraps作用

​ 被装饰后的函数其实已经是另外一个函数了(函数名等函数属性会发生改变),为了不影响,Python的functools模块中提供了一个叫wraps的decorator来消除这样的副作用。

#将上面代码中的@wraps(func)去掉,执行下面代码
print(addition_func.__doc__)    #None
print(addition_func.__name__)   #with_logging
#添加 @wraps(func)后,就变得“正常”了,wraps装饰装饰器内的函数,就会代指元信息和函数。
带参数的装饰器

@wraps(func)就是一个带参数的装饰器;上面使⽤@decorator语法时,是在应⽤⼀个以单个函数作为参数的⼀个包裹函数。我们可以编写⼀下能返回⼀个包裹函数的函数。

#将每个函数的运行,单独生成一份日志
from functools import wraps
def logit(logfile='out.log'):
    def logging_decorator(func):
        @wraps(func)
        def wrapped_function(*args, **kwargs):
            log_string = func.__name__ + " was called"
            print(log_string)
            # 打开logfile,并写⼊内容
            with open(logfile, 'a') as opened_file:
            # 现在将⽇志打到指定的logfile
                opened_file.write(log_string + '\n')
        return wrapped_function
    return logging_decorator
@logit()
def myfunc1():
pass
myfunc1()
# Output: myfunc1 was called
# 现在⼀个叫做 out.log 的⽂件出现了,⾥⾯的内容就是上⾯的字符串
@logit(logfile='func2.log')
def myfunc2():
pass
myfunc2():
pass
myfunc2()
myfunc2()
# Output: myfunc2 was called
# 现在⼀个叫做 func2.log 的⽂件出现了,⾥⾯的内容就是上⾯的字符串

转载于:https://www.cnblogs.com/notfind/p/11548496.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值