《Dive into python3》:Chapter 6 闭包与生成器之闭包

在这一章中,主要学习内容是:用一个复数名词转换的案例学习高级正则表达式、返回其他函数的函数、闭包与生成器等。

首先我们简单的了解下闭包:

'''
一、定义理解:下面是一个简单的闭包,在外面定义的makeInc()我们称为外函数,里面定义的inc()为内函数,
内函数使用到了外面的临时变量,并且外函数的返回值是内函数的引用。这样就构成了一个闭包

二、在内函数中想修改闭包变量时有两种方法:
1、在python3中,可以用nonlocal关键字声明一个变量,表示这个变量不是局部变量空间的变量需要向上一层变
量空间找这个变量。
2、修改变量为可变数据类型,如列表

三、闭包实现原理:python中的闭包是由函数调用创建的。这里,对makeInc的调用为函数inc中引用的x创建了
一个绑定(把外函数的临时变量送给内函数绑定在一起)。每次调用makeInc都会创建此函数的新实例,但每个
实例都有一个指向x的不同绑定的链接。

四、用途:替换硬编码常量、终结全局、提供一致的功能签名、实现面向对象'''


def makeInc(x):
    def inc(y):
        nonlocal x
        x+=1
        print(x+y)
    return inc
inc5 = makeInc(5)
inc10 = makeInc(10)

if __name__ == '__main__':
    inc5(5)
    inc10(5)

一、英语名词单数形式转换成复数形式

plural1.py
import re

def plural(noun):          
    if re.search('[sxz]$', noun):                   '① 中括号表示匹配括号里的字符之一'       
        return re.sub('$', 'es', noun)
        
    elif re.search('[^aeioudgkprt]h$', noun):       '② ^这是一个非的符号,表示匹配到的字符不是括号里的任何一个'
        return re.sub('$', 'es', noun)
       
    elif re.search('[^aeiou]y$', noun):      
        return re.sub('y$', 'ies', noun)
     
    else:
        return noun + 's'

这里解释下:

① 如果在名词noun中匹配到s,x,z中的任意一个字符,那么将这些词末尾加上es,返回复数名词。

②如果名词是以除了aeioudgkprtyi以外的字母加h结尾的,那么将这些词末尾加上es,返回复数名词。

③记忆分组:我还想指出可以将该两条正则表达式合并起来(一条查找是否应用该规则,另一条实际应用规则),使其成为一条
正则表达式。它看起来是下面这个样子:其中多数内容看起来应该很熟悉:使用了在 案例研究:分析电话号码 中用到的记忆
分组。该分组用于保存字母 y 之前的字符。然后在替换字符串中,用到了新的语法: \1,它表示“嘿,记住的第一个分组呢?
把它放到这里。”在此例中, 记住了 y 之前的 c ,在进行替换时,将用 c 替代 c,用 ies 替代 y 。(如果有超过一个的记忆分
组,可以使用 \2 和 \3 等等。)

二、函数列表

plural2.py
import re

def match_sxz(noun):
    return re.search('[sxz]$', noun)

def apply_sxz(noun):
    return re.sub('$', 'es', noun)

def match_h(noun):
    return re.search('[^aeioudgkprt]h$', noun)

def apply_h(noun):
    return re.sub('$', 'es', noun)

def match_y(noun):                             
    return re.search('[^aeiou]y$', noun)
        
def apply_y(noun):                             
    return re.sub('y$', 'ies', noun)

def match_default(noun):
    return True

def apply_default(noun):
    return noun + 's'

rules = ((match_sxz, apply_sxz),               
         (match_h, apply_h),
         (match_y, apply_y),
         (match_default, apply_default)
         )

def plural(noun):           
    for matches_rule, apply_rule in rules:       
        if matches_rule(noun):
            return apply_rule(noun)

三、匹配模式列表(用到了闭包)

plural3.py
import re

def build_match_and_apply_functions(pattern,search,replace):
    def matches_rule(word):
        return re.search(pattern,word)
    def apply_rule(word):
        return re.sub(search,replace,word)
    return (matches_rule,apply_rule)

patterns = \
    (
        ('[sxz]$',           '$', 'es'),
        ('[^aeioudgkprt]h$', '$', 'es'),
        ('(qu|[^aeiou])y$',  'y$','ies'),
        ('$',                '$', 's')

    )
rules = [build_match_and_apply_functions(pattern,search,replace)
         for (pattern,search,replace) in patterns]
def plural(noun):
    for matches_rule,apply_rule in rules:
        if matches_rule(noun):
            return apply_rule(noun)
        

if __name__ == '__main__':
    import sys
    if sys.argv[1:]:
        print(plural(sys.argv[1]))
    else:
        print(__doc__)

四、匹配模式文件

将代码与数据独立开,这样可维护性更好。

plural4.py
import re
def build_match_and_apply_functions(pattern,search,replace):
    def matches_rule(word):
        return re.search(pattern,word)

    def apply_rule(word):
        return re.sub(search,replace,word)
    return (matches_rule,apply_rule)

rules = []
with open('plural4-rules.txt',encoding='utf-8') as pattern_file:
    for line in pattern_file:
        pattern,search,replace = line.split(None,3)
        rules.append(build_match_and_apply_functions(pattern,search,replace))

def plural(noun):
    for matches_rule,apply_rule in rules:
        if matches_rule(noun):
            return apply_rule(noun)
        
if __name__ == '__main__':
    import sys
    if sys.argv[1:]:
        print(plural(sys.argv[1]))
    else:
        print(__doc__)

在带参数运行时遇到下面这样一个错误,我还没想清楚这是哪里出了问题,需要发个求助帖了

猜你喜欢

转载自blog.csdn.net/qq_38576427/article/details/81983334