每日一道面试题------2019.9.5

解释下Python装饰器,并举例说明如何使用

首先解释下什么叫装饰器,所谓装饰器本质是一个python函数,可以在其他函数调用该函数的时候,不修改原代码而添加新的功能,减少代码的复用率,装饰器的返回值也是一个函数对象。

总结就是:不修改被装饰函数的调用方式、不修改被调用函数的源代码

前提了解:

作用域:

全局作用域:定义的文件级别的变量、函数名,在全局不能访问到局部的变量

局部作用域:定义在函数的内部 ,在局部能访问全局的变量,不能修改全局定义的变量

全局变量适用于当前文件中所有方法的调用,若要修改全局变量,要在全局修改。若函数内部未查找到变量,会去全局变量中查找,若都不存在,会报错。

举例:

a = 1


def test():
    a = 10 /*存在局部变量,取局部变量*/
    print(a) /*a=10*/


test()
print(a) /*a=1*/
a = 1


def test():
    # 没有局部变量,调用全局变量
    print(a) /*a=1*/


test()
print(a) /*a=1*/

闭包函数定义:函数内部定义的函数,包含对外部作用域的引用(不是全局变量)

举例:

# 内部函数调用外部函数作用域变量
def outer():
    x=1
    def inner():
        print(x)
    inner()
outer()

装饰器:

无参装饰器  举例:

def old():
    print('我是原来的代码')


def outer(func):
    def inner():
        func()
        print('我是装饰器代码,这里写新功能')
    return inner


old = outer(old) # 也可以写成 @outer
old()

有参装饰器 考虑在调用原函数的时候,有些要传参有些不需要的情况

def old():
    print('我是原来的代码')


def outer(func):
    def inner(*args, **kwargs):  #主要是这里参数的修改
        desc = func(*args, **kwargs) # 接收原函数的返回值
        print('我是装饰器代码,这里写新功能')
        return desc
    return inner


old = outer(old) # 也可以写成 @outer 使用装饰器
old()

若存在一个函数被多个装饰器装饰,执行顺序是按照从上往下执行的

类装饰器 顾名思义就是装饰的方法是一个类,可以用于管理类自身,或者用来拦截实例创建调用以管理实例。

举例:类装饰函数

class Test:
    def __init__(self, func):
        print('test init')
        # 打印出调用装饰器的函数
        print('func name is %s ' % func.__name__)
        self.func = func

    # 调用方法
    def __call__(self, *args, **kwargs):
        print('装饰器中的功能')
        #调用的函数需要传参数时
        self.func(*args, **kwargs)
        
        
@Test
def aa(name, age):
    print('final',name ,age)


aa('tom',10)

运行结果:

每日一道面试题------2019.9.5_第1张图片

 

 

 

 

你可能感兴趣的:(每日一练)