如何忽略 python 字典创建中的错误?

How to Ignore errors in python dictionary creation?

我有多种格式的图像数据(对于一堆 if/else 语句来说太多了,以至于不合理或看起来很干净)。 我创建了许多 (python) 类 来根据格式读取数据,即 framesource.pngsframesource.mat。使用 def __init__(self,path):... 在我的 UI(使用 pyqtgraph)中,用户提供了数据路径和数据类型。我想要一本字典来将用户选择映射到正确的阅读功能,例如:

### these would be set via the gui
filepath= 'some//path//to//data'
source_type = 'pngs' 

### in the code for processing
import variousReaderFunctions # like framesource.pngs and framesource.mat
readerFuncDict={ 
    ...
    'pngs':framesource.pngs(filepath)
    'mat' :framesource.mat(filepath)
    ...
    }
resulting_frames = readerFuncDict[source_type]

每个数据集可能包含一种或多种数据类型的数据,这些数据可以在 filepath 中找到。但是,如果不存在类型(例如,如果有 .png 而没有 .mat),则字典将失败并显示 [Errno 2] No such file or directory: 'some//path//to//data//.mat'。后面的代码不是 运行,即使它没有返回到被窃听的字典键。

有没有办法将字典创建设置为不初始化 运行 错误的键? 像

readerFuncDict={}
listOfOptions=[...,'pngs','mat',...]
listOfFunctions=[...,'framesource.pngs(filepath)','framesource.mat(filepath)',...]
for idx,opt in enumerate(listOfOptions):
    try:
        readerFuncDict[opt]=listOfOptions[idx]
    except:
        continue

resulting_frames = readerFuncDict[source_type]
with resulting_frames as _frames:...

我试过在字典中保留 类 未初始化,即:

readerFuncDict={ 
    ...
    'pngs':framesource.pngs
    'mat' :framesource.mat
    ...
    }
resulting_frames = readerFuncDict[source_type].__init__(self,path=filepath)
with resulting_frames as _frames:...

但它给出了一个 <class 'AttributeError'> : __enter__ 回溯 :

File "/home/cnygren/miniconda3/envs/snipres/lib/python3.9/site-packages/pyqtgraph/flowchart/Node.py", line 311, in update
    out = self.process(**strDict(vals))
File "/home/cnygren/snipy/Flowchart_v1.py", line 133, in process
    with resulting_frames as _frames:

您可以定义一个包装器,如果引发函数调用和异常:return None

def try_or_none(func, *args, **kwargs):
    try:
        return func(*args, **kwargs)
    except Exception:
        pass

然后你可以使用 dict() 调用初始化你的字典,并向那里传递一个生成器,它将过滤具有 None 值的对:

from math import sqrt

...

some_dict = dict((key, value) for key, value in (
    ("a", try_or_none(sqrt, 4)),
    ("b", try_or_none(sqrt, 9)),
    ("c", try_or_none(sqrt, -1)),  # will throw an exception
    ("d", try_or_none(sqrt, 16))
) if value is not None)

看起来有点麻烦,但这是最简单的解决方案。

另一种方法是实现某种“惰性”字典。看看下一个问题(如果你有兴趣)Setup dictionary lazily.