问题:
我有代码查找文件并打开它。默认情况下,它会查找以#######
开头的文件(每个#都是一个数字)。
问题有时是文件名##-#####
,有时是#####
。
如果找不到文件,我想尝试一种方法尝试寻找文件可以写入的其他两种方式。
找不到文件时发生IOError异常。我在想的是有一个除了声明说:
except File2:
Look for ##### in myfindFileFunction()
if file is still not found run except File3
except File3:
Look for ##-#### in myfindFileFuction()
except:
print "File not found"
我不确定如何设置自定义异常以这种方式工作,和/或是否有更多pythonic方式完全执行此操作...
设置一个模式或三个可能的文件名并迭代思考,直到找到文件更好?
答案 0 :(得分:5)
使用try / except确实是一种非常pythonic(和快速)的做事方式。
你不仅要权衡它是否是pythonic,而是这种方法在可读性方面有什么影响。当您在6个月内再次查看代码时,您是否仍会快速理解代码?别人会吗?
我通常会确保处理这类事情的稍微复杂的try / except子句得到很好的评论。除此之外......这是一种非常合理的方式。
另外,为了让您放心地考虑性能,当一个人在两种方法之间做出决定时,这是一个常见的问题,请看一下:Python if vs try-except,你会发现try / except结构在Python中很快。 ..真的很快。
答案 1 :(得分:3)
不需要自定义例外
import errno
try:
open('somefile')
except IOError as e:
if e.errno == errno.ENOENT:
open('someotherfilename')
else:
raise e
(这是* nix-我不确定你是否使用Windows)
答案 2 :(得分:1)
定义自己的异常很容易 - 只需创建一个派生自Exception的类。 doco很清楚。
但是,似乎不需要为每种文件类型创建单独的异常,或者根本不创建任何异常。你可以这样做:
files = ('#######', "##-#####', '#####') fh = None for f in files: try: fh = open(f) break except IOError as e: if e.errno in (errno.ENOENT,): pass else: raise if not fh: ## all three tries failed
在if
周围使用e.errno
可让您确定哪些IO错误意味着转到下一个文件,哪些是您想要了解的错误。文件不存在(errno.ENOENT
)表示尝试下一个文件。但其他人喜欢“打开太多文件”(errno.ENFILE
)可能需要不同的响应。