您的位置:首页 > 编程语言 > Python开发

【脚本语言系列】关于Python基础知识装饰器,你需要知道的事

2017-07-22 20:44 771 查看

如何使用装饰器(Decorators)

知识准备

对象复制

# -*- coding:utf-8 -*-
def hello(name = "AllenMoore"):
return "Hello " + name

print hello()

greet = hello
print greet()

del hello
print hello()


Hello AllenMoore
Hello AllenMoore
Hello AllenMoore

---------------------------------------------------------------

NameError                     Traceback (most recent call last)

<ipython-input-6-8d0abdde1ee5> in <module>()
10 del hello
11 print greet()
---> 12 print hello()

NameError: name 'hello' is not defined

* __函数内嵌函数__


# -*- coding:utf-8 -*-
def hello(name = "AllenMoore"):
print "Now You are hello out."

def hi():
return "Now You are hi."

def bye():
return "Now You are bye."

print hi()
print bye()
print "Now you are hello in."

hello()
hi()


Now You are hello out.
Now You are hi.
Now You are bye.
Now you are hello in.

---------------------------------------------------------------

NameError                     Traceback (most recent call last)

<ipython-input-9-ec0e2edbd16b> in <module>()
16
17 hello()
---> 18 hi()

NameError: name 'hi' is not defined

* __函数作为返回值__


# -*- coding:utf-8 -*-
def hello(name = "AllenMoore"):
def hi():
return "Now You are hi."

def bye():
return "Now You are bye."

if name == "AllenMoore":
return hi
else:
return bye

the_greet = hello()
print the_greet
print the_greet()


* __函数作为参数__


# -*- coding:utf-8 -*-
def hello():
return "Now You are hello."

def doSthAhead(func):
print "do something ahead."
print func()

doSthAhead(hello)


装饰器

简单的装饰器

# -*- coding:utf-8 -*-
def the_new_decorator(a_func):
def wrap_the_func():
print "Before exec the func, I do sths."
a_func()
print "After exec the func, I do sths."
return wrap_the_func

def the_func_needDecoration():
print "Here We need some decoration."

the_func_needDecoration()
the_func_needDecoration = the_new_decorator(the_func_needDecoration)
the_func_needDecoration()


Here We need some decoration.
Before exec the func, I do sths.
Here We need some decoration.
After exec the func, I do sths.


# -*- coding:utf-8 -*-
def the_new_decorator(a_func):
def wrap_the_func():
print "Before exec the func, I do sths."
a_func()
print "After exec the func, I do sths."
return wrap_the_func

@the_new_decorator
def the_func_needDecoration():
print "Here We need some decoration."

the_func_needDecoration()
the_func_needDecoration = the_new_decorator(the_func_needDecoration)
print the_func_needDecoration.__name__


Before exec the func, I do sths.
Here We need some decoration.
After exec the func, I do sths.
wrap_the_func


# -*- coding:utf-8 -*-
from functools import wraps

def the_new_decorator(a_func):
def wrap_the_func(a_func):
print "Before exec the func, I do sths."
a_func()
print "After exec the func, I do sths."
return wrap_the_func

@the_new_decorator
def the_func_needDecoration():
"""Decorater the func!"""
print "Here We need some decoration."

the_func_needDecoration()
the_func_needDecoration = the_new_decorator(the_func_needDecoration)
print the_func_needDecoration.__name__


---------------------------------------------------------------

TypeError                     Traceback (most recent call last)

<ipython-input-40-1349141083db> in <module>()
12     print "Here We need some decoration."
13
---> 14 the_func_needDecoration()
15 the_func_needDecoration = the_new_decorator(the_func_needDecoration)
16 print the_func_needDecoration.__name__

TypeError: wrap_the_func() takes exactly 1 argument (0 given)






- __含参数的装饰器__




- __嵌入函数的装饰器__


# -*- coding:utf-8 -*-
from functools import wraps

def logit(logfile='out.log'):
def logging_decorator(func):
@wraps(func)
def wrapped_function(*args, **kwargs):
log_string = func.__name__ + " just called"
print log_string
with open(logfile, 'a') as opened_file:
opened_file.write(log_string + '\n')
return wrapped_function
return logging_decorator

@logit()
def the_func1():
pass

the_func()

@logit(logfile='func2.log')
def the_func2():
pass

the_func1()
the_func2()


the_func just called
the_func1 just called
the_func2 just called


装饰器类

# -*- coding:utf-8 -*-
# Only for Python 2.x

class logit(object):
def __init__(self, logfile='out.log'):
self.logfile = logfile

def __call__(self, func):
log_string = func.__name__ + " just called"
print log_string
with open(self.logfile, 'a') as opened_file:
opened_file.write(log_string + '\n')
self.notify()
def notify(self):
pass

@logit()
def the_func1():
pass

class email_logit(logit):
'''When call the function, send email to the manager.'''
def __init__(self, email = 'allenmoore@theproject.com', *args, **kwargs):
self.email = email
super(logit, self).__init__(*args, **kwargs)

def notify(self):
pass

@email_logit()
def the_func2():
pass

the_func1()
the_func2()


the_func1 just called
the_func2 just called

---------------------------------------------------------------

AttributeError                Traceback (most recent call last)

<ipython-input-34-65071749c9a2> in <module>()
27
28
---> 29 @email_logit()
30 def the_func2():
31     pass

<ipython-input-34-65071749c9a2> in __call__(self, func)
7         log_string = func.__name__ + " just called"
8         print log_string
----> 9         with open(self.logfile, 'a') as opened_file:
10             opened_file.write(log_string + '\n')
11         self.notify()

AttributeError: 'email_logit' object has no attribute 'logfile'


使用场景

模板(Blueprint)

# -*- coding:utf-8 -*-
from functools import wraps
def decorator_func(func):
@wraps(func)
def decorated(*args, **kwargs):
if not do_run:
return "func no run"
return func(*args, **kwargs)
return decorated

@decorator_func
def func():
return "func just run"

do_run = True
print func()


func just run

- __授权(Authorization)__


# -*- coding:utf-8 -*-
# Only For Python 2.x
from functools import wraps
from urllib import request

def requires_auth(func):
@wraps(func)
def decorated(*args, **kwargs):
auth = request.authorization
if not auth or not check_auth(auth.username, auth.password):
authenticate()
return func(*args, **kwargs)
return decorated

@requires_auth
def auth_func():
return "auth is done."

auth_done = auth_func()
print auth_done


---------------------------------------------------------------

ImportError                   Traceback (most recent call last)

<ipython-input-26-27f77c33258d> in <module>()
1
2 from functools import wraps
----> 3 from urllib2 import request
4
5 def requires_auth(func):

ImportError: cannot import name request

- __日志(Logging)__


# -*- coding:utf-8 -*-
from functools import wraps

def logit(func):
@wraps(func)
def with_logging(*args, **kwargs):
print func.__name__ + " just called."
return func(*args, **kwargs)
return with_logging

@logit
def addition_func(x):
"""Do sth."""
return x + x

result = addition_func(4)
print result


addition_func just called.
8


什么是装饰器(Decorators)

装饰器是改变其他函数的功能的函数。

为何使用装饰器(Decorators)

装饰器能够使代码更为简洁。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐