gpt4 book ai didi

python - 可以接受使用自定义异常作为哨兵值吗?

转载 作者:行者123 更新时间:2023-12-01 05:13:15 29 4
gpt4 key购买 nike

考虑 Python 中的一种情况,其中使用 getattr 动态获取方法或值。

def message(obj, msg, *args, **kwargs):
result = getattr(obj, msg, None)
if result is not None:
try:
return result(*args, **kwargs)
except TypeError:
return result

...只是,等等——这并不是一个很好的行为。即使这是一个错误的 getattr 调用,无论如何都会隐式返回 None —— 对于此类函数来说,这不一定是很好的行为。

为了在没有好的和体面的哨兵(我无论如何都知道)的情况下确定一个可靠的“相信我,你不想返回这个”值,我考虑设置 的默认值getattr 到引发异常的函数。通过这种方式,糟糕的搜索应该总是显而易见的并被捕获,除非“另一个人”决定表现得可爱并将这个无用的哨兵作为一个属性。

class _BadMessageException(Exception):
pass

def _did_not_find(*args, **kwargs):
raise BadMessageException

def _raise_right_exception(msg, obj):
if not isinstance(msg, basestring):
raise TypeError("Message '{}' was not a string".format(msg))
else:
raise AttributeError("Bad message '{}' sent to object '{}'".format(msg, obj))

这样,当消息返回 None 时,它​​至少总是处于向上状态,因为它在您要求它查找的地方找到了 None。然后它还会引发您期望的异常:没有此类方法/ivar 的对象的 AttributeError、传递的参数太多的 TypeError 等等。 编辑: 当然,我发布了错误的代码片段第一次。这是更正后的函数。

def message(obj, msg, *args, **kwargs):
result = getattr(obj, msg, _did_not_find)
try:
return result(*args, **kwargs)
except TypeError:
if not args or kwargs:
return result
else:
_raise_right_exception(msg, obj)
except _BadMessageException:
_raise_right_exception(msg, obj)

感觉就像有很多额外的代码只是为了确保以正确的方式失败。一个引发异常的函数,它只是一个 McGuffin 引发首选异常的函数,只是为了安抚eafp半神...... Hrrm。

是否有更简单的语法来声明有效的“失败”标记,无论是在这种情况下还是在返回值未知或无法保证的其他情况下?

最佳答案

根本不要给getattr()一个默认值;让 it 引发 AttributeError 甚至 TypeError 以获得错误的 msg 值,而不是:

>>> getattr(object(), 'foo')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'object' object has no attribute 'foo'
>>> getattr(object(), 42)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: getattr(): attribute name must be string

这使您的方法变得简单:

def message(obj, msg, *args, **kwargs):
result = getattr(obj, msg)
try:
return result(*args, **kwargs)
except TypeError:
return result

或者,对于您的更新版本,如果您传入了参数,则与重新加注大致相同:

def message(obj, msg, *args, **kwargs):
result = getattr(obj, msg)
try:
return result(*args, **kwargs)
except TypeError:
if not args and not kwargs:
# assume attribute access was desired
return result
raise

关于python - 可以接受使用自定义异常作为哨兵值吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23745416/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com