我有一个清理特定字符的函数:
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 字符串文字,但很多遗留代码使用字节字符串,你通常必须支持它们。