python decorators
来源:互联网 发布:vb中过程的主要作用 编辑:程序博客网 时间:2024/05/29 02:31
Decorator is a very expressive language feature in python. It helps developers to write cleaner, modular code that is easier to extend and maintain. It also helps implement AOP and decorator pattern in python.
Decorator syntax
To declare a decorator function, we can define a function that takes a another function as argument and returns a function. The usage of decorator is very simple, just add a line begins with '@' symbol and the name of the decorator before the function to be decorated.
The effect is when we call foo function, besides print "hello world" message, the message "decorator message" is also printed. That is, the decorator function extends foo function's behavior.
The code above is equivalent to:
Decorators can also accept arguments, as long as it returns a decorator function that takes a function as argument.
The example above is equivalent to :
A more practical example
Here is a more practical example. We create a tracable decorator which is a debugging utility. It will keep records of the number of times that a function decorated with it is invoked.
If we run the code, it will prints that foo1 function is called three times and foo2 function is called twice.
As the example showed, the code for implementing tracing is separated from business logic code contained within foo1 and foo2. The maintainability of the program is much higher than if the code for tracing is mixed with business logic code.
Summary
We got several benefits from decorator.
First, it helps achieve a better separation of business logic code and auxiliary code.
Second, it helps finding out where the auxiliary is used because decorator employs a very special syntax.
Third, we can extend or change our business logic without having to change existing code. New code can be implemented as a decorator.
References:
Charming Python: Decorators make magic easy
Decorators for Functions and Methods
PythonDecorators
Decorator syntax
To declare a decorator function, we can define a function that takes a another function as argument and returns a function. The usage of decorator is very simple, just add a line begins with '@' symbol and the name of the decorator before the function to be decorated.
1 def decorator(func):
2 def new_func():
3 print "decorator message"
4 func()
5 return new_func
6
7 @decorator
8 def foo():
9 print "hello world"
10
11 foo()
2 def new_func():
3 print "decorator message"
4 func()
5 return new_func
6
7 @decorator
8 def foo():
9 print "hello world"
10
11 foo()
The effect is when we call foo function, besides print "hello world" message, the message "decorator message" is also printed. That is, the decorator function extends foo function's behavior.
The code above is equivalent to:
1 def decorator(func):
2 def new_func():
3 print "decorator message"
4 func()
5 return new_func
6
7 def foo():
8 print "hello world"
9
10 foo = decorator(foo)
11 foo()
2 def new_func():
3 print "decorator message"
4 func()
5 return new_func
6
7 def foo():
8 print "hello world"
9
10 foo = decorator(foo)
11 foo()
Decorators can also accept arguments, as long as it returns a decorator function that takes a function as argument.
1 def decorator_with_arg(arg):
2 def decorator(func):
3 def new_func():
4 print arg
5 func()
6 return new_func
7 return decorator
8
9 @decorator_with_arg("arg for decorator")
10 def foo():
11 print "hello world"
12
13 foo()
2 def decorator(func):
3 def new_func():
4 print arg
5 func()
6 return new_func
7 return decorator
8
9 @decorator_with_arg("arg for decorator")
10 def foo():
11 print "hello world"
12
13 foo()
The example above is equivalent to :
1 def decorator_with_arg(arg):
2 def decorator(func):
3 def new_func():
4 print arg
5 func()
6 return new_func
7 return decorator
8
9 def foo():
10 print "hello world"
11
12 foo = decorator_with_arg("arg for decorator")(foo)
13 foo()
The decorator_with_arg function creates a closure, so that the arg argument can still be used after the decorator_with_arg returned. Since it's possible for a decorator to accept arguments, the decorator's behavior can changed based on the argument passed in. So it's possible to write more flexible code.2 def decorator(func):
3 def new_func():
4 print arg
5 func()
6 return new_func
7 return decorator
8
9 def foo():
10 print "hello world"
11
12 foo = decorator_with_arg("arg for decorator")(foo)
13 foo()
A more practical example
Here is a more practical example. We create a tracable decorator which is a debugging utility. It will keep records of the number of times that a function decorated with it is invoked.
1 trace_log = {}
2
3 def tracable(func):
4 def decorated_func(*arg, **kwarg):
5 if not trace_log.has_key(func.__name__):
6 trace_log[func.__name__] = 1
7 else:
8 trace_log[func.__name__] += 1
9 func(*arg, **kwarg)
10
11 return decorated_func
12
13 def print_trace_log():
14 for key, value in trace_log.items():
15 print "%s called %d times"%(key, value)
16
17 @tracable
18 def foo1():
19 print "foo1"
20
21 @tracable
22 def foo2(arg, kwd="keyword arg"):
23 print "foo2"
24 print arg
25 print kwd
26
27 @tracable
28 def foo3():
29 print "foo3"
30
31 foo1()
32 foo1()
33 foo1()
34 foo2(12)
35 foo2(13)
36
37 print_trace_log()
2
3 def tracable(func):
4 def decorated_func(*arg, **kwarg):
5 if not trace_log.has_key(func.__name__):
6 trace_log[func.__name__] = 1
7 else:
8 trace_log[func.__name__] += 1
9 func(*arg, **kwarg)
10
11 return decorated_func
12
13 def print_trace_log():
14 for key, value in trace_log.items():
15 print "%s called %d times"%(key, value)
16
17 @tracable
18 def foo1():
19 print "foo1"
20
21 @tracable
22 def foo2(arg, kwd="keyword arg"):
23 print "foo2"
24 print arg
25 print kwd
26
27 @tracable
28 def foo3():
29 print "foo3"
30
31 foo1()
32 foo1()
33 foo1()
34 foo2(12)
35 foo2(13)
36
37 print_trace_log()
If we run the code, it will prints that foo1 function is called three times and foo2 function is called twice.
As the example showed, the code for implementing tracing is separated from business logic code contained within foo1 and foo2. The maintainability of the program is much higher than if the code for tracing is mixed with business logic code.
Summary
We got several benefits from decorator.
First, it helps achieve a better separation of business logic code and auxiliary code.
Second, it helps finding out where the auxiliary is used because decorator employs a very special syntax.
Third, we can extend or change our business logic without having to change existing code. New code can be implemented as a decorator.
References:
Charming Python: Decorators make magic easy
Decorators for Functions and Methods
PythonDecorators
- python decorators
- Python Decorators
- [Python]Decorators
- python -decorators
- Decorators I: Introduction to Python Decorators
- python 的函数Decorators
- python标注,@decorators
- Decorators and Functional Python
- Decorators and Functional Python
- Python Decorators入门
- python装饰器Decorators
- Decorators and Functional Python
- Python Decorators 3
- Python Decorators 装饰器
- Python decorators example
- 深入浅出 Python Decorators
- Python Decorators入门 (一)
- python decorators, classmethod and staticmethod
- 生活啊 啊啊
- VC远程连接MYSQL失败原因收集:mysql_real_connect()
- 设计模式分类
- Linux虚拟文件系统二
- HashMap和Hashtable及HashSet的区别
- python decorators
- 跨应用程序共享session Sharing Session Across Applications
- Linux系统调用
- android的listactivity实例
- Hashtable 哈希表
- 敏捷开发宣言--《敏捷开发的艺术》读书笔记0
- Java数据类型.
- 90后不是只会吃喝玩乐
- VC应用 —— 个性化你的工具栏图标(摘自网络)