SilentGhost:dis.dis确实展示了潜在的概念/执行复杂性。毕竟,OP抱怨原来的替换链太“笨拙”,而不是太“慢”。
我建议不要在非不可避免的情况下使用正则表达式;他们只是增加了概念上的开销和速度损失。在这里使用translate() 恕我直言,这是一个错误的工具,而且在概念上没有原始替换链那么简单和通用。
所以你说 tamaytoes,我说 tomahtoes:原始解决方案在清晰度和通用性方面非常好。它一点也不笨拙。为了使其更密集和更参数化,请考虑将其更改为
phone_nr_translations = [
( ' ', '', ),
( '(', '', ),
( ')', '', ), ]
def sanitize_phone_nr( phone_nr ):
R = phone_nr
for probe, replacement in phone_nr_translations:
R = R.replace( probe, replacement )
return R
当然,在这个特殊的应用程序中,您真正想要做的只是消除任何不需要的字符,因此您可以简化:
probes = ' ()'
def sanitize_phone_nr( phone_nr ):
R = phone_nr
for probe in probes:
R = R.replace( probe, '' )
return R
回想起来,我不太清楚为什么要将电话号码转换为整数——这只是错误的数据类型。这可以通过以下事实来证明:至少在移动网络中,+ 和# 甚至更多是拨号字符串中的有效字符(拨号,字符串——看到了吗?)。
但除此之外,清理用户输入电话号码以获得标准化和安全的表示是一个非常非常有效的问题 - 只是我觉得你的方法太具体了。为什么不将消毒方法重写为非常通用的东西而不变得更复杂呢?毕竟,您如何确保您的用户不会在该 Web 表单字段中输入其他异常字符?
所以你真正想要的不是dis - 允许特定字符(在 unicode 5.1 中定义了大约十万个代码点,那么如何赶上这些?),而是 允许那些在拨号字符串中被认为是合法的字符。你可以用正则表达式来做到这一点......
from re import compile as _new_regex
illegal_phone_nr_chrs_re = _new_regex( r"[^0-9#+]" )
def sanitize_phone_nr( phone_nr ):
return illegal_phone_nr_chrs_re.sub( '', phone_nr )
...或带有一组:
legal_phone_nr_chrs = set( '0123456789#+' )
def sanitize_phone_nr( phone_nr ):
return ''.join(
chr for chr in phone_nr
if chr in legal_phone_nr_chrs )
最后一节可以写在一行上。此解决方案的缺点是您从 Python 中迭代输入字符,而不使用 str.replace() 甚至正则表达式提供的潜在更快的 C 遍历。然而,在任何情况下,性能都取决于预期的使用模式(我相信你首先会截断你的手机 nrs,对吗?所以要处理的将是许多小字符串,而不是几个大字符串)。
请注意这里的几点:我力求清晰,这就是为什么我尽量避免过度使用缩写。 chr 代表character,nr 代表number 和R 代表返回值(更可能是,呃,在标准库中使用的retval)在我的风格书中。编程是关于让事情被理解和完成,而不是程序员编写接近 gzip 空间效率的代码。现在看,最后一个解决方案在...
legal_phone_nr_chrs = set( '0123456789#+' )
def sanitize_phone_nr( phone_nr ): return ''.join( chr for chr in phone_nr if chr in legal_phone_nr_chrs )
...如果需要,两行代码,而 OP 的代码...
class Phone():
def __init__ ( self, input ): self.phone = self._sanitize( input )
def __str__ ( self ): return self.phone
def _sanitize ( self, input ): return input.replace( ' ', '' ).replace( '(', '' ).replace( ')', '' )
...几乎不能压缩到四行以下。看看严格的 OOP 解决方案给您带来了哪些额外的负担?我相信大多数时候它可以被排除在外。