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 stringdef 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 ----ClosuresClosure 并没有复杂到可怕的地步:它只是一个“内部”函数,指代“包含该函数的那个‘外部’函数的本地名称(即变量)”。下面是个阳春的例子: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 Reference 和
Python in a Nutshell 中关于字符串
translate 方法以及
string 模块中的
maketrans 函数的文档。
发表于 @ 2007年04月24日 11:26:00|评论(loading...)|编辑