zoukankan      html  css  js  c++  java
  • 装饰器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 + '
    ')
    		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 的⽂件出现了,⾥⾯的内容就是上⾯的字符串
    
  • 相关阅读:
    17. Letter Combinations of a Phone Number
    16. 3Sum Closest
    15. 3Sum
    14. Longest Common Prefix
    13. Roman to Integer
    12. Integer to Roman
    11. Container With Most Water
    10. Regular Expression Matching
    9. Palindrome Number
    8. String to Integer (atoi)
  • 原文地址:https://www.cnblogs.com/notfind/p/11548496.html
Copyright © 2011-2022 走看看