= try except模式?

3 投票
4 回答
1586 浏览
提问于 2025-04-16 01:25

我发现这个设计模式经常出现:

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 个回答

6

难道没有更好的方法来做这个吗?

其实是有的——那就是“函数”...:

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(在某些字体中,0o的形状很像),那么默默地把他们的输入变成0就不太好了。所以,我觉得这种情况并不常见,也不太建议在语言中使用特殊的语法形式,甚至不需要内置函数。

但是像safeget这样的辅助函数的好处在于,你我可以在设计问题上和平地达成不同的看法(也许我们只是习惯做不同类型的软件!),同时让每个人都能在自己的“工具”模块中轻松拥有自己想要的辅助函数!-)

10

你可能更适合使用 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)
5

我会使用一个辅助函数:

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')

这样可以把处理错误的复杂逻辑放在一个地方,这样你的函数就会更整洁,每个参数在视图函数中只用一行代码。

撰写回答