= try except模式?
我发现这个设计模式经常出现:
try: year = int(request.GET['year'])
except: year = 0
在这个try
块里,可能会因为键不存在或者它不是一个int
而失败,但我其实并不在乎这些。我只需要最后得到一个合理的值。
难道没有更好的方法来做到这一点吗?或者至少能用一行代码实现?像这样:
year = int(request.GET['year']) except 0
你们也会用这种模式吗?
在你们回答之前,我想说我已经知道request.GET.get('year',0)
这个方法,但这样仍然可能会出现值错误。把这个放在一个try/catch块里来捕获值错误,只是让默认值在我的代码中出现了两次。对我来说,这样更糟糕。
4 个回答
难道没有更好的方法来做这个吗?
其实是有的——那就是“函数”...:
def safeget(adict, key, type, default):
try: return type(adict.get(key, default))
except (ValueError, TypeError): return default
year = safeget(request.GET, 'year', int, 0)
顺便说一下,我觉得我从来没有用过这种“模式”——你忽略的各种错误情况似乎应该单独处理,因为这关系到用户界面(UI)。比如说,缺少一个可选字段的默认值是可以接受的,但如果有人错误地输入了,比如说201o
(在某些字体中,0
和o
的形状很像),那么默默地把他们的输入变成0
就不太好了。所以,我觉得这种情况并不常见,也不太建议在语言中使用特殊的语法形式,甚至不需要内置函数。
但是像safeget
这样的辅助函数的好处在于,你我可以在设计问题上和平地达成不同的看法(也许我们只是习惯做不同类型的软件!),同时让每个人都能在自己的“工具”模块中轻松拥有自己想要的辅助函数!-)
你可能更适合使用 get()
方法。
year = int(request.GET.get("year", 0))
这个方法会把年份设置为请求中获取的 'year' 值,如果这个键不存在,它会返回 0。这样可以避免出现 KeyError 错误,但如果请求中的 'year' 值不能转换成整数,还是可能会出现 ValueError 错误。
关于你的问题(try/except),在 Python 中有一个常用的做法叫做 EAFP。
编辑:
如果你真的很担心,为什么不自己写一个方法来处理呢:
def myGet(obj, key, type, defaultval):
try:
return type(obj.get(key, defaultval))
except ValueError:
return defaultval
# In your code
year = myGet(request.GET, 'year', int, 0)
我会使用一个辅助函数:
def get_int(request, name, default=0):
try:
val = int(request.GET[name])
except (ValueError, KeyError):
val = default
return val
然后:
year = get_int(request, 'year')
这样可以把处理错误的复杂逻辑放在一个地方,这样你的函数就会更整洁,每个参数在视图函数中只用一行代码。