概括多次尝试的好方法,除了

good way to generalize multiple try except

我在代码的 for 循环中有 15 个 try except 语句。我认为它可以推广,但我无法找到解决方案。我该怎么做。

for item in results:

    try:
        a = item.something()
    except:
        a = ""

    try:
        b = item.something2()
    except:
        b = ""

    b = re.sub(r'\W+', ' ', b)
    b = b.strip()

    try:
        c = item.something3()
        parsed_url = urlparse(b)
        if not bool(parsed_url.scheme):
            break
    except:
        c = ""

    try:
        d = item.something4()
    except:
        d = ""

按照答案中的建议,我将其概括为

def attrs(self, call_fun):
    try:
        return call_fun()
    except:
        return ""

但是当我打电话给

   a = self.attrs(item.get("data-a")) 

我在调用 try: except: 时得到了一个空白输出,给出了正确的输出。 怎么了?

不更改您的数据:

def try_something(callable):
    try:
        return callable()
    except:
        return ""

a = try_something(item.something)

请记住,您可以自由地将可调用对象(函数或方法)作为参数传递给 Python 函数。这利用了那个。然而,通过重构 item 的 class 可能仍然有更好的方法来做到这一点,但这需要更多信息。

还有,你不知道抛出的异常类型吗?如果这样做,您应该在 except 声明中更加明确。

当前接受的答案只有在可调用对象不接受任何参数时才有效,执行一个小片段并抑制它可能引发的某个错误使用上下文管理器会更容易:

class catch:
    def __init__(self,err_type):
        valid = True
        if isinstance(err_type, tuple):
            valid = all(issubclass(e, BaseException) for e in err_type)
        else:
            valid = issubclass(err_type, BaseException)
        if not valid:
            raise TypeError("can only catch exception types, not {!r}".format(err_type))
        self.catch_err = err_type

    def __enter__(self):
        return self
    def __exit__(self,typ, err, tb):
        self.err = err #keep a reference if you want to access later.
        if isinstance(err, self.catch_err):
            return True

然后你可以 运行 你的个人部分是这样的:

a = b = c = d = "" #default if any fail.

with catch(Exception): #should really specify what kind of exception you are catching!
    a = item.something()


with catch(Exception): #should really specify what kind of exception you are catching!
    b = item.something2()

b = re.sub(r'\W+', ' ', b)
b = b.strip()

with catch(Exception): #should really specify what kind of exception you are catching!
    c = item.something3()
    parsed_url = urlparse(b)
    if not bool(parsed_url.scheme):
        break

with catch(Exception): #should really specify what kind of exception you are catching!
    d = item.something4()

当您执行 a = self.attrs(item.get("data-a")) 时,您调用 item.get("data-a") 时没有任何错误检查并将 return 值传递给 self.attrs,除非尝试调用它的结果是可调用的在 self.attrs 中将引发 TypeError。您需要传递一个不接受任何参数的可调用函数才能使接受的答案起作用,这只需要您拥有 python 2.7+ 版以支持 with 语句。

顺便说一下,如果 itemdict 那么 dict.get 永远不会引发异常,它在 the documentation

get(key[, default])
Return the value for key if key is in the dictionary, else default. If default is not given, it defaults to None, so that this method never raises a KeyError.