Python Cookbook 第二版 汉化版 [Recipe 1.9] 简化字符串 translate 方法的用法

Recipe 1.9. Simplifying Usage of Strings' translate Method
Recipe 1.9. 简化字符串 translate 方法的用法


Credit: Chris Perkins, Raymond Hettinger


问题

您常常希望使用高效的字符串 translate 方法,但却很难记住该方法和 string.maketrans 函数的详细用法,因此您想要一种能在通常情况下简化其用法的包装方案(facade)。


解法

正如 Recipe 1.10 中所述,字符串的 translate 方法非常强大切颇具伸缩性。然而恰恰是因为这种强大威力和可伸缩性所带来的使用难度,使得我们似乎有必要使用一种“包装方案(facade)”为其添加一个前端接口,以便简化其在通常情况下的用法:

import string
def translator(frm='', to='', delete='', keep=None):
    if len(to) == 1:
        to = to * len(frm)
    trans = string.maketrans(frm, to)
    if keep is not None:
        allchars = string.maketrans('', '')
        delete = allchars.translate(allchars, keep.translate(allchars, delete))
    def translate(s):
        return s.translate(trans, delete)
    return translate


讨论

我常常发现自己想要使用字符串的 translate 方法来做些事情,但每次我都不得不停下来仔细回想其详细用法(请参见 Recipe 1.10 查看更多关于详细用法的信息)。因此我自己编写了一个 class(之后又将其重制为 factory closure ,即本条目“解法”中所呈现的方案),将多种可能的处理封装到一个较为简易的 facade 当中。现如今,若我想要一个函数,使其只保留给定集合中的字符,我就可以简单地建构并使用这个函数:

>>> digits_only = translator(keep=string.digits)
>>> digits_only('Chris Perkins : 224-7992')
'2247992'

若要从字符串中移除某个字符集中的字符,也同样简单:

>>> no_digits = translator(delete=string.digits)
>>> no_digits('Chris Perkins : 224-7992')
'Chris Perkins : -'

若要用单一个字符替换一个字符集合,可以这样做:

>>> digits_to_hash = translator(from=string.digits, to='#')
>>> digits_to_hash('Chris Perkins : 224-7992')
'Chris Perkins : ###-####'

虽然上面这个用法可能看起来有点特殊,但于我而言确为时不时就会出现的任务。

在本条目中,我不得不作出一个带有随意性的设计决定,即在 delete 参数与 keep 参数交叠的情况下,让 delete 参数“吃掉” keep 参数:

>>> trans = translator(delete='abcd', keep='cdef')
>>> trans('abcdefg')
'ef'

对于您自己的应用而言,在指定了 keep 的情况下,或许忽略 delete 更好;而在两者同时被指定的情况下,或许最好是抛出异常(因为在同一个 translator 调用中同时指定两者毕竟没有多大实际意义)。同样,如 Recipe 1.8 和 Recipe 1.10 所述,本条目中的代码仅适用于普通字符串,不适用于 Unicode 字符串,因为 Unicode 字符串的 translate 方法与普通字符串(即以 byte 为处理单位的字符串)的同名方法有所区别。

---- BOX BEGIN ----
Closures

Closure 并没有复杂到可怕的地步:它只是一个“内部”函数,指代“包含该函数的那个‘外部’函数的本地名称(即变量)”。下面是个阳春的例子:

def make_adder(addend):
    def adder(augend): return augend+addend
    return adder

执行 p = make_adder(23) 就会制造出一个 closure ,即内部函数 adder ,其指代一个被绑定为数值 23 的名称。接着,q = make_adder(42) 又制造出一个 closure ,其内的 addend 被绑定到数值 42。此时 q 与 互不干涉,两者可以愉快且独立地共生。如此一来,我们就可以执行诸如 pprint p(100), q(100) 这样的语句,并得到结果为 123 142 的输出。

在实际当中,您可能常常会看到,make_adder 会被看作 closure ,而不是以带有学究气的、生硬冗长的“返回 closure 的函数”来解释。幸运的是,上下文经常能够明晰具体情况。将 make_adder 称为 factory (或 factory function ,工厂函数)既准确又精炼;您还可以说它是 closure factory ,以便阐明它建造并返回 closures 的事实,而不是 class 或 class instances 。
---- BOX E N D ----


请参见

Recipe 1.10 包括本条目中 translate(keep=...) 的等价方案、更多关于 translate 方法的信息,以及适用于 Unicode 字符串的等价方案;在 Library ReferencePython in a Nutshell 中关于字符串 translate 方法以及 string 模块中的 maketrans 函数的文档。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值