Python食谱-1.9.字符串的translate方法的简化用法

原文作者:Chris Perkins, Raymond Hettinger
中文编译:Tony(digitalsatori)

问题

想使用Python字符串对象强大的 translate 方法,却总困惑于其参数的设置和 string.maketrans 的用法。怎么才能有效的简化使用呢?

解决方法

Python食谱1.10 中介绍的字符串的 translate 方法强大而又灵活,但是我们绝对有必要为它创建一个简化使用的用户界面。一个factory函数,返回一个closure就能轻松化繁为简:

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

讨论

来看看这个函数是如何简化操作的。

如果需要一个函数保留属于一个指定集合中的字符,可以这样来:

>>> 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:###-####'

在函数使用中,如果keep和delete参数的值有重合之处,delete将优先于keep起作用,比如:

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

同样,translator 的使用如同在 Python食谱1.8Python食谱1.10 中介绍的一样只能适用于普通字符串,不能用于Unicode字符串。参见 Python食谱1.10 了解如何使用Unicode字符串不同的translate方法来创建类似的功能。

Closures

closure 并不很复杂,它表示:内部函数所引用的函数名称是包含该内部函数的外部函数的本地变量。一个最简单的例子:

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

执行 p = make_adder(23) 创建一个closure,其中内部函数 adder 引用一个变量 addend 其与数值23关联。 q = make_adder(42) 则创建了另外一个closure,其中 addend 与数值42关联。p和q完全独立存在互不影响。如果我们执行 print p(100), q(100) 会得到结果123, 142。

实际中我们往往直接称 make_adder 为closure, 其实更确切些应该称其为factory(factory函数),或者也可以称其为‘closure factory‘以表示其创建并返回closure的行为。

参见

Python食谱1.10 中关于translate的介绍,Python in a Nutshell和Python库函数手册中关于字符串模块,及其translate,maketrans方法的介绍

2 Responses to “Python食谱-1.9.字符串的translate方法的简化用法”

  1. GarykPatton 说道:

    I think I will try to recommend this post to my friends and family, cuz it’s really helpful.

  2. unurotaylor 说道:

    must check with confident suprisely

Leave a Response