python 中闭包理解,及函数string.maketrans(),string.translate()

时间:2023-01-30 11:01:08

在写程序的时候,可能有写需求,需要用到对字符进行交换或过滤,python中提供了两个函数

        string.maketrans(from, to)   -> 重from一一映射到to中,所以要求两个字符串一样长,如果

                                                             两个都为空,则为全部字符,那么不会出现替换

        string.translate(charactor_map, delete_charactors) 

                                                         ->第一个参数是第一个函数的返回值,是一个映射表,具体是

                                                             怎样的,我不清楚,知道的可以帮助解释一下

                                                             第二个参数是要删除在string中的字符

在python的cookbook的例子:

#! /usr/bin/python
#-*- coding:utf-8 -*-
#Filename: translator.py
#Author: xiaobing
#E-mail: xiaobingzhang29@gmail.com
#Date: 2013-11-05
#Description:

import string

def translator(frm = '', to = '', delete = '', keep = None):
"""这是一个工具函数,用于将一个字符串中的字符对应转换为另外的字符
1,如果指定了detete,可以删除掉需要转换的字符串中的字符;
2,如果指定了keep,那么只能是keep中的字符能保留下来;
3,若同时指定delete和keep,则用keep = set(keep) - set(delete),
即保留下来的是经过keep减去delete中的字符
"""
#如果想把所有frm中的字符转换为一个字符,因为映射表的from 和 to必须相同长度,
#所以这里乘以len(frm)
if len(to) == 1:
to = to * len(frm)

#构造一个映射表,指定为,frm和to对应的位置替换,不能交叉,所以指定了相同长度
trans = string.maketrans(frm, to)

#如果需要保留的字符不为空的话,那么(keep - delete)是要剩下的,其余的都将删掉
if keep is not None:
#这个是一个所有的字符的映射表,可以当一个字符串处理,即,他包含了所有的字符串
allchars = string.maketrans('','')

#能最终保留下来的字符
remainkeep = keep.translate(allchars, delete)
#将要删除的字符,这个 = 所有的字符,减去最终保留的字符
delete = allchars.translate(allchars, remainkeep)

#一个闭包函数
def translate(s):
return s.translate(trans, delete)
return translate


if __name__ == '__main__':
translate = translator(delete = 'abcd', keep = 'cdef')
s = 'abcdefh'
print translate(s)
#结果为: ef
#解释:根据第三条,同时指定了keep 和delete,那么最终保留的字符为
# keep = set(keep) - set(delete) -> keep = 'ef'

digit_only = translator(keep = string.digits)
s = 'abcdefg123456'
print digit_only(s)
#结果为:123456

strings_only = translator(delete = string.digits)
s = 'abcdefg123456'
print strings_only(s)
#结果为:abcdefg

frm = 'abc'
to = 'R'
translate = translator(frm, to)
s = 'abcefghijk'

print translate(s)
#结果为:RRRefghijk
看来上面的例子的解析,应该能明白这两个函数的意思了,借此,说一下python的闭包

实际上,这是第一次接触闭包,我的理解是这样的:

在官方的讲解中,把闭包太神话了,让人望而生畏,其实就是那些数学家弄的名词吓着了

只要理解是什么意思就ok了,不必去确切的知道,到底什么叫闭包,当然理解了更好。


在python中,如下的代码:

def getAreaOfRound(pi):
""""得到一个圆的面积"""

def area(r):
return r * r * pi

return area

if __name__ == '__main__':
pi = 3.14
area = getAreaOfRound(pi)
r = 5
print area(5)
#结果: 78.5
r = 10
print area(10)
#结果:314.0
解释:在getAreaOfRound(pi)中,传入了一个pi变量,pi的作用域是getAreaOfRound整个函数,所以

            内部函数area() 可以访问到,当程序执行到area的定义时,只是把pi传递下去,其他的什么都

            没做,最后一句返回了内部函数的引用;

            这是这个语言的特点,函数可以当作参数来使用,所以,返回的参数,直接传递半径就可以计算

            面积了,这里要说明的是,pi变量的值,已经存在的返回的函数中了,在官方这个叫*变量,

            他的值是第一次赋值的时候的pi,这个值不会销毁,直到这个程序结束后才释放,但在 getAreaOfRound()

           函数中,这个变量已经不存在了,这就是说的闭包,简单的说,就是返回的函数里面可以引用

           外层函数的值,但切记,不能在内部函数(area)中使用这样的语句:pi = pi + 1,因为,在python

            中会先 解析左边,看见是一个变量,所以需要赋值(python中的变量必须赋初值才能使用), 但

           在后面的pi + 1,有引用了外层的pi,这两个名字是相同的,解释器就不知道是那个了,所以会

           报改变量在本地不存在的错误

闭包的好处:

            类似上面的函数,可以一次写一些参数,只传一次参数,后面都只传一个输入值,不用再写麻烦

            的参数表达式了,因为第一次传入的参数可以被后面的闭包函数直接引用,减少了 很多麻烦,如

            果理解了这样的格式,会很美观,但如果不理解,也可以每次都把全部参数传入,进行运算,

            但在一定的情况下,可能闭包的效率要高些,如:

             当输入的参数,经过一些计算后,把中间结果传入到闭包函数内部中,当返回闭包函数时,下次

             调用的时候,就少了计算的中间过程