使用抛出异常的lambda过滤列表

5 投票
3 回答
4008 浏览
提问于 2025-04-18 14:26

我在使用 psutil 这个工具时,可以得到一个进程的列表;我想从中筛选出特定名称的进程。

filter(lambda p: p.name()=="x", psutil.process_iter())

不过,psutil.Process.name() 这个函数可能会出现错误... 这样的话,filter 就会出问题,并把这个错误抛给我。

有没有那种 filter_noexception 的函数或者写法,还是说我需要自己把 p.name() 放到一个能处理错误的函数里呢?

3 个回答

0

filter 这个函数里没有这样的处理,但正如文档所说:

要注意,filter(function, iterable) 相当于 [item for item in iterable if function(item)],前提是 function 不是 None。

考虑到这一点,我会自己处理这些过程:

def filter_noexception(func, iter):
    result = []
    for i in iter:
        try:
            if func():
                result.append(i)
        except:
            pass
    return result

filtered_processes = filter_noexception(lambda p: p.name() == "x", psutil.process_iter())
1

我添加了一个叫做 replace_exception 的函数装饰器:

def replace_exception(original, default=None):
   def safe(*args, **kwargs):
       try:
          return original(*args, **kwargs)
       except:
          return default
   return safe

现在我可以让我的函数变得更安全了:

filter(replace_exception(lambda p: p.name()=="x"), psutil.process_iter())
2

你可以这样做:

def try_get_name(process_instance):
    try:
        return process_instance.name()
    except:
        return ""


filter(lambda p: try_get_name(p)=="x", psutil.process_iter())

撰写回答