Python 以适用于 STR 和 Unicode 的方式使用翻译的方式是什么?



我有一个清理特定字符的函数:

def _clean_name(name):
    return name.translate(None, "n ").replace('.', '_')

现在这个函数也必须支持 Unicode,所以我最终得到了这个版本:

def _clean_name(name):
    if type(name) is unicode:
        return name.translate({ord('n'): None, ord(' '): None, ord('.'): ord('_')})
    else:
        return name.translate(None, "n ").replace('.', '_')

但这对我来说并不太蟒蛇。 有人有更好的解决方案吗?

这可能比 Pythonic 更像是一种黑客方式——但一个优点是它将删除代码重复,并且可能应该适用于 unicode 的子类(如果需要,您肯定需要检查它!

因此,考虑到类型对象是可调用的,并且 unicode 和 str 都实现了 join 操作:

def _clean_name(name):
    return type(name)().join(
#          ^^^^^^^^^^^^
#           build an empty str or unicode object
        [{'.': '_', 'n':'', ' ':''}.get(c,c) for c in name]
    )

不幸的是,即使在Python 3中,translate对字节字符串和Unicode字符串也有不同的语法。 有一种maketrans方法可以帮助构建转换表,但只有 Python 3 有 Unicode 版本。 我会为 Python 2.x 编写一个版本,但否则使用您的方法版本来调用正确版本的translate

import string
def unicode_maketrans(s,t,d=None):
    '''Generate a translation dictionary.
       Map ordinals in s to ordinals in t.
       Map ordinals in d to None.
    '''
    D = dict(zip(map(ord,s),map(ord,t)))
    if d:
        D.update({ord(c):None for c in d})
    return D
str_table = string.maketrans('.','_')
str_del = 'n '
uni_table = unicode_maketrans(u'.',u'_',u'n ')
def clean_name(name):
    if isinstance(name,unicode):
        return name.translate(uni_table)
    else:
        return name.translate(str_table,str_del)
print repr(clean_name('this is.a testn'))
print repr(clean_name(u'this is.a testn'))

输出:

'thisis_atest'
u'thisis_atest'

_clean_name受保护的,所以它是文件/类本地的。我要么假设该类适用于unicode字符串,要么在清理时进行转换:

def _clean_name(name):
    if isinstance(name, str):
        name = unicode(str)
    return name.translate({ord('n'): None, ord(' '): None, ord('.'): ord('_')})

是的,人们喜欢说 Python 的鸭子类型,但在你拥有的代码中,知道 name 是一个 unicode 字符串,而不是一个字节字符串真是太好了。Python 3 甚至承认type('foo') == str是一个错误,你99% 的时间都希望 unicode 字符串文字,但很多遗留代码使用字节字符串,你通常必须支持它们。

最新更新