python :编写装饰器

简单装饰器

def log_time(func):  # 此函数的作用时接受被修饰的函数的引用test,然后被内部函数使用
    def make_decorater():
        print('现在开始装饰')
        func()
        print('现在结束装饰')
    return make_decorater  # log_time()被调用后,运行此函数返回make_decorater()函数的引用make_decorater
 
@log_time  # 此行代码等同于,test=log_time(test)=make_decorater
def test():
    print('我是被装饰的函数')
test()  # test()=make_decorater()


调试结果
D:\pycharm_project\装饰器\venv\Scripts\python.exe D:/pycharm_project/装饰器/venv/装饰器.py 现在开始装饰 我是被装饰的函数 现在结束装饰 Process finished with exit code 0

带参的

形参

def log_time(func):
    def make_decorater(*args,**kwargs):  # 接受调用语句的实参,在下面传递给被装饰函数(原函数)
        print('现在开始装饰')
        test_func = func(*args,**kwargs)  # 如果在这里return,则下面的代码无法执行,所以引用并在下面返回
        print('现在结束装饰')
        return test_func  # 因为被装饰函数里有return,所以需要给调用语句(test(2))一个返回,又因为test_func = func(*args,**kwargs)已经调用了被装饰函数,这里就不用带()调用了,区别在于运行顺序的不同。
    return make_decorater
 
 
@log_time
def test(num):
    print('我是被装饰的函数')
    return num+1
 
a = test(2)  # test(2)=make_decorater(2)
print(a)

传入注解的参数注意!有两个return,log_time函数也要return

def get_parameter(*args,**kwargs):  # 工厂函数,用来接受@get_parameter('index.html/')的'index.html/'
    def log_time(func):
        def make_decorater():
            print(args,kwargs)
            print('现在开始装饰')
            func()
            print('现在结束装饰')
        return make_decorater
    return log_time              
 
@get_parameter('index.html/')
def test():
    print('我是被装饰的函数')
    # return num+1
 
test()  # test()=make_decorater()

D:\pycharm_project\装饰器\venv\Scripts\python.exe D:/pycharm_project/装饰器/venv/装饰器.py
('index.html/',) {}
现在开始装饰
我是被装饰的函数
现在结束装饰
 
Process finished with exit code 0

装饰器:在不修改函数源代码的基础上,添加函数功能

一个简单的装饰器

1
2
3
4
5
6
7
8
9
10
11
def  log_time(func):   # 此函数的作用时接受被修饰的函数的引用test,然后被内部函数使用
     def  make_decorater():
         print ( '现在开始装饰' )
         func()
         print ( '现在结束装饰' )
     return  make_decorater   # log_time()被调用后,运行此函数返回make_decorater()函数的引用make_decorater
 
@log_time   # 此行代码等同于,test=log_time(test)=make_decorater
def  test():
     print ( '我是被装饰的函数' )
test()   # test()=make_decorater()
1
2
3
4
5
6
D:\pycharm_project\装饰器\venv\Scripts\python.exe D: / pycharm_project / 装饰器 / venv / 装饰器.py
现在开始装饰
我是被装饰的函数
现在结束装饰
 
Process finished with exit code  0

 当被装饰的函数有形参时

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def  log_time(func):
     def  make_decorater( * args, * * kwargs):   # 接受调用语句的实参,在下面传递给被装饰函数(原函数)
         print ( '现在开始装饰' )
         test_func  =  func( * args, * * kwargs)   # 如果在这里return,则下面的代码无法执行,所以引用并在下面返回
         print ( '现在结束装饰' )
         return  test_func   # 因为被装饰函数里有return,所以需要给调用语句(test(2))一个返回,又因为test_func = func(*args,**kwargs)已经调用了被装饰函数,这里就不用带()调用了,区别在于运行顺序的不同。
     return  make_decorater
 
 
@log_time
def  test(num):
     print ( '我是被装饰的函数' )
     return  num + 1
 
=  test( 2 )   # test(2)=make_decorater(2)
print (a)
1
2
3
4
5
6
7
D:\pycharm_project\装饰器\venv\Scripts\python.exe D: / pycharm_project / 装饰器 / venv / 装饰器.py
现在开始装饰
我是被装饰的函数
现在结束装饰
3
 
Process finished with exit code  0

 

当@装饰器后有参数时

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def  get_parameter( * args, * * kwargs):   # 工厂函数,用来接受@get_parameter('index.html/')的'index.html/'
     def  log_time(func):
         def  make_decorater():
             print (args,kwargs)
             print ( '现在开始装饰' )
             func()
             print ( '现在结束装饰' )
         return  make_decorater
     return  log_time
 
@get_parameter ( 'index.html/' )
def  test():
     print ( '我是被装饰的函数' )
     # return num+1
 
test()   # test()=make_decorater()
1
2
3
4
5
6
7
D:\pycharm_project\装饰器\venv\Scripts\python.exe D: / pycharm_project / 装饰器 / venv / 装饰器.py
( 'index.html/' ,) {}
现在开始装饰
我是被装饰的函数
现在结束装饰
 
Process finished with exit code  0

猜你喜欢

转载自www.cnblogs.com/daysn/p/10796469.html
今日推荐