使用Python脚本打开包含变音符号的文件时遇到麻烦。自然,我以为我可以用Unicode utf8修正来解决这个问题,但事实并非如此...
我最终使用了mbcs(默认值为cp1252)
然后我写了我想写的更清洁的声明,
def len(fname):
i = -1
try:
with open(fname, encoding='mbcs') as f:
for i, l in enumerate(f):
pass
except UnicodeDecodeError:
try:
i = -1
with open(fname, encoding='utf8') as f:
for i, l in enumerate(f):
pass
except UnicodeDecodeError:
i = -1
with open(fname) as f:
for i, l in enumerate(f):
pass
return i + 2 # 2 because it starts at -1 not 0
如注释中所述,几乎可以肯定这是所有错误的答案……但是,如果您确实确实需要执行以下操作,则可以通过以下方法简化操作:
避免重复自己的一般解决方案是使用循环。您有3次相同的代码,唯一的不同是encoding
,因此请循环使用3种编码。(在您的情况下,第三个循环根本没有传递一个encoding
,因此您必须知道该参数的默认值,但是docs或help
会告诉您。)唯一的麻烦是您显然不想处理第三种情况下的例外;最简单的方法是在所有异常均失败的情况下提出最后一个异常。
当我们这样做时:无需预先声明i
您的操作方式;该for
循环只是要在任何你放在那里0和擦除启动。这也意味着+2
结尾处是错误的。但是,首先有一种更简单的方法来获取可迭代对象的长度:只需将其馈送到使用生成器表达式的对象中即可。ilen
用C编写的自定义函数将是理想的,但是人们已经测试了各种不同的Python实现,并且sum(1 for _ in iterable)
几乎与完美的解决方案一样快,而且非常简单,因此这是最常见的习惯用法。如果您不希望这样做,请将其作为函数lien
分解出来并调用它,并为其提供漂亮的文档字符串和/或注释。或者只是pip install more-itertools
,然后您可以致电more_itertools.ilen(f)
。
无论如何,将它们放在一起:
def len(fname):
for encoding in 'mbcs', 'utf8', None:
try:
with open(fname, encoding=encoding) as f:
return sum(1 for line in f)
except UnicodeDecodeError as e:
pass
raise e
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句