首页 > 解决方案 > 如何忽略python字典创建中的错误?

问题描述

我有多种格式的图像数据(对于一堆 if/else 语句来说太多了,不合理或看起来很干净)。我创建了许多(python)类来读取数据,具体取决于格式framesource.pngs,即framesource.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. 但是,如果不存在类型(例如,如果有 .pngs 但没有 .mat),则字典将失败并显示[Errno 2] No such file or directory: 'some//path//to//data//.mat'. 即使后面的代码没有引用错误的 dict 键,它也不会运行。

有没有办法将字典创建设置为简单地不初始化遇到错误的键?就像是

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:

标签: pythondictionarytry-catch

解决方案


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

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

然后你可以使用dict()call 初始化你的字典并传递一个生成器,它将过滤具有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)

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

另一种方法是实现某种“惰性”字典。看看下一个问题(如果你有兴趣)懒惰地设置字典


推荐阅读