Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Error handling Pythonic指定默认值的方法_Error Handling_Python - Fatal编程技术网

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的理念。