1.15 使用装饰器改变函数行为
装饰器能封装一个函数,并改变它的行为,通过示例是理解它们的最好方式,本节中我们演示了实际应用中的一些示例。
1.15.1 准备工作
还记得我们在前面章节中将函数作为另一个函数的参数、函数作为一个变量、函数中返回函数等介绍吗?最重要的是,你还记得那个圆柱体的例子吗?如果你掌握了这些,装饰器只是小菜一碟。在本节的示例中,我们将对给定的字符串建立清理操作管道:给定一个混合大小写并带有标点符号的字符串,我们使用装饰器对它进行清理,这些操作还很容易进行扩展。
1.15.2 操作方法
我们写一个简单的装饰器来进行文本操作。
from string import punctuation
def pipeline_wrapper(func):
def to_lower(x):
return x.lower()
def remove_punc(x):
for p in punctuation:
x = x.replace(p,'')
return x
def wrapper(args,*kwargs):
x = to_lower(args,*kwargs)
x = remove_punc(x)
return func(x)
return wrapper
@pipeline_wrapper
def tokenize_whitespace(inText):
return inText.split()
s = "string. With. Punctuation?"
print tokenize_whitespace(s)
1.15.3 工作原理
我们先从以下两行开始。
s = "string. With. Punctuation?"
print tokenize_whitespace(s)
我们声明了一个字符串变量,然后想对它进行清理,使之满足以下特性。
将字符串转为小写。
清除标点符号。
返回一个词列表。
我们用字符串s作为参数,调用了tokenize_whitespace函数,我们来看看这个函数。
@pipeline_wrapper
def tokenize_whitespace(inText):
return inText.split()
这个函数很简单:输入一个字符串,函数采用空格作为分隔符将它进行分割,并返回一个词列表。接下来我们使用装饰器来改变这个函数的行为,这个装饰器就是@pipeline_wrapper,它是以简便的方式调用以下语句。
tokenize_whitespace = pipeline_wrapper (clean_tokens)
我们仔细看看这个装饰器函数。
def pipeline_wrapper(func):
def to_lower(x):
return x.lower()
def remove_punc(x):
for p in punctuation:
x = x.replace(p,'')
return x
def wrapper(args,*kwargs):
x = to_lower(args,*kwargs)
x = remove_punc(x)
return func(x)
return wrapper
pipeline_wrapper返回了wrapper函数,在后者中,最后的返回语句是返回func,这是我们传递给wrapper的原始函数,wrapper改变了我们原来的pipeline_wrapper函数的行为。pipeline_wrapper的输入先被to_lower()函数修改了,转成了小写。随后是remove_punc()函数,将标点符号清除。最后的输出如下。
['string', 'with', 'punctuation']
以上结果就是我们所要的:清除标点符号,转为小写字符,最后形式是词的列表。