Error handling Pythonic指定默认值的方法
以这一行为例:Error handling Pythonic指定默认值的方法,error-handling,python,Error Handling,Python,以这一行为例: some_value = lst.attr[idx] 这里有两个可能的错误,attr可能不存在,idx可能超出范围 有什么优雅的方法可以减少这种说法吗?理想情况下,可以这样做: some_value = lst.attr[idx] or default_value (不要在家里这样做。这只适用于正确定义的计算结果为某个值的表达式。) 当然我能做到: try: some_value = lst.attr[idx] except: some_value = def
some_value = lst.attr[idx]
这里有两个可能的错误,attr
可能不存在,idx
可能超出范围
有什么优雅的方法可以减少这种说法吗?理想情况下,可以这样做:
some_value = lst.attr[idx] or default_value
(不要在家里这样做。这只适用于正确定义的计算结果为某个值的表达式。)
当然我能做到:
try:
some_value = lst.attr[idx]
except:
some_value = default_value
但是如果我在一个任务中呢?例如:
print [x.attr[idx] for x in y]
if hasattr(lst, "attr"):
attr = lst.attr
else:
attr = {}
在这种情况下,处理错误和分配默认值的pythonic方法是什么?即使存在一个线性,也会非常复杂。例如,这个仍然不能处理索引问题:
some_value = getattr(lst, 'attr', {idx: default_value})[idx]
当对象中有“attr”时,我建议为您的
lst
编写一些getter
class C(object):
attr = "attr on class"
lst = C()
print lst.attr if hasattr(lst,'attr') else "default value"
当没有属性“attr”时
class C(object):
#attr = "attr on class"
pass
lst = C()
print lst.attr if hasattr(lst,'attr') else "default value"
在这种情况下,处理错误和分配默认值的pythonic方法是什么
我觉得“Pythonic分配默认值的方法”*要么是处理异常(正如您在问题中已经提到的那样),要么是编写自己的getter。您需要决定在这里尝试实现什么。使用“错误”一词可能会产生误导 如果您实际上试图处理将错误类型的对象传递给函数的情况,那么您不想处理该情况,应该引发异常 如果您试图允许在一系列不同的类型上使用您的函数,那么这并不是一个真正的错误,使用默认值可能是合理的 最简单的选择是首先测试属性是否存在。例如:
print [x.attr[idx] for x in y]
if hasattr(lst, "attr"):
attr = lst.attr
else:
attr = {}
我假设lst.attr
是一个字典,在这种情况下,您可以像这样处理默认值:
lst.attr.get(idx, default_value)
切勿使用try
/语句,除非您没有指定要捕获的异常。你最终可能会掩盖比你预想的更多的东西
对于您的最后一段代码,我认为您不应该尝试在一行中解决它。可读性很重要。我对下面的代码不满意,但如果用更具描述性的名称替换x
、y
和attr
,情况会有所改善
attrs = [(x.attr if hasattr(x) else {}) for x in y]
print [attr.get(idx, default_value) for attr in attrs]
编写函数并使其足够智能:
def get_attr_with_index_and_default(obj, attr_name, index, default):
try:
return getattr(obj, attr_name)[index]
except (AttributeError, IndexError):
return default
print [get_attr_with_index_and_default(x, 'attr', idx, some_default) for x in y]
如果您控制x
类,您可以将其用作方法,或将其用作描述符,但在我看来,这并不值得,而且会导致代码模糊和难以跟踪错误 您的问题没有简单、优雅的解决方案。例如,如果必须使用可用于列表理解的单行线来完成,则可以执行以下操作:
# If lst.attr is a dict.
some_value = getattr(lst, 'attr', {}).get(idx, default_value)
# OR
some_value = lst.attr.get(idx, default_value) if hasattr(lst, 'attr') else default_value
# OR
some_value = lst.attr[idx] if hasattr(lst, 'attr') and idx in lst.attr else default_value
# If lst.attr is a sequence.
some_value = lst.attr[idx] if idx < len(getattr(lst, 'attr', ())) else default_value
# OR
some_value = lst.attr[idx] if hasattr(lst, 'attr') and idx < len(lst.attr) else default_value
#如果lst.attr是dict。
some_value=getattr(lst,'attr',{}).get(idx,默认_值)
#或
如果hasattr(lst,'attr')为默认值,则some_value=lst.attr.get(idx,默认值)
#或
如果hasattr(lst,'attr')和lst.attr else中的idx为默认值,则some_value=lst.attr[idx]
#如果lst.attr是一个序列。
如果idx
这不是很常见的任务,所以(我想)没有内置的解决方案。但您可以编写自己的getter函数并在任何地方使用它(也可以在列表理解中)?那是蟒蛇式的。“如果我在作业上下文中该怎么办”显示的是打印语句,而不是作业。您能否澄清该陈述以及除
之外的可能导致的问题?不清楚为什么除
之外的是不可接受的。请澄清。@S.Lott-列表理解是作业的一个例子。想想if-else块和三元运算符之间的区别。“列表理解是赋值的一个例子”?不,不是。没有分配任何内容。这很令人困惑。您能否解释一下,在print
语句周围添加标准的except
子句会产生什么确切的问题。假设列表理解的计算结果为[1,2,3]
。如果2
计算失败,我希望我的列表是[1,'x',3]
(或其他什么),并且应该打印出来。按照你的建议,如果[1,2,3]
失败,我唯一能打印的就是某个地方的错误
。我不会使用hasattr
-它在引擎盖下使用try/except
。只需将if
语句替换为try:
,将else:
替换为除了AttributeError:
。当然符合EAFP的理念。