【问题标题】:Collect all key errors收集所有关键错误
【发布时间】:2020-02-21 15:31:23
【问题描述】:

我想创建一个类来存储 init 中发生的关键错误列表。

class Basic:
    missing_view_data_columns = []

    def __init__(self, some_dict):
        self.some_dict = some_dict
        try:
            self.basic_1 = self.some_dict['basic_1']
            self.basic_2 = self.some_dict['basic_2']

        except KeyError as e:
            self.add_missing_data_column(e)

    @classmethod
    def add_missing_data_column(cls, column_name):
        cls.missing_view_data_columns.append(column_name)


class Specific(Basic):

    def __init__(self, some_dict):
        super().__init__(some_dict)
        try:
            self.specific_1 = self.some_dict['specific_1']
            self.specific_2 = self.some_dict['specific_2']

        except KeyError as e:
            self.add_missing_data_column(e)


rem = Specific({})

print(f"missing_keys: {rem.missing_view_data_columns}")

这是我的方法,但它不起作用。以下代码将仅打印出现的第一个关键错误。 我也可以说它看起来不太好,因为我需要写两次相同的异常。

您能给我建议如何创建此功能吗?

【问题讨论】:

  • 如果specific_1不在字典里,你还要检查specific_2是否在字典里吗?
  • dict会通过从网页下载数据交给class,我需要知道这个dict是否包含init中定义的每个key。
  • 为什么两个键查找都在 try 中?如果第一个引发KeyError,第二个保证会被忽略,因为try 块将在第一行退出
  • 我只是想展示我想要实现的目标。在我的代码中,我计划拥有超过 2 个键,并且我不想创建 10 次尝试,除了块。
  • @Beorn 也许您可以将 try except 包装在每个键的 for 循环中?

标签: python exception keyerror


【解决方案1】:

您可以实现自己的字典:

from collections.abc import Mapping

class MissingDict(Mapping):
    def __init__(self, d, cls):
      self._d = d
      self.cls = cls

    def __getitem__(self, i):
      if i in self._d:
          return self._d[i]

      self.cls.add_missing_data_column(i)

    def __iter__(self): return iter(self._d)
    def __len__(self):  return len(self._d.keys())

这将存储字典实例并在您尝试访问新键时更新您的类的缺失列表。像这样使用:

class Basic:
    missing_view_data_columns = []

    def __init__(self, some_dict):
        self.some_dict = MissingDict(some_dict, self)
        self.basic_1 = self.some_dict['basic_1']
        self.basic_2 = self.some_dict['basic_2']

    @classmethod
    def add_missing_data_column(cls, column_name):
        cls.missing_view_data_columns.append(column_name)


class Specific(Basic):

    def __init__(self, some_dict):
        super().__init__(some_dict)
        self.specific_1 = self.some_dict['specific_1']
        self.specific_2 = self.some_dict['specific_2']


rem = Specific({})

print(f"missing_keys: {rem.missing_view_data_columns}")

显示:

missing_keys: ['basic_1', 'basic_2', 'specific_1', 'specific_2']

【讨论】:

    【解决方案2】:

    我已经修改了您的代码,以循环遍历您要检查的每个键:

    class Basic:
        missing_view_data_columns = []
    
        def __init__(self, some_dict):
            self.some_dict = some_dict
            keys = ['basic_1', 'basic_2']
            for key in keys:
                self.check_for_key_error(key)
    
        def check_for_key_error(self, key):
            try:
                self.key = self.some_dict[key]
            except KeyError as e:
                self.add_missing_data_column(e)
    
        @classmethod
        def add_missing_data_column(cls, column_name):
            cls.missing_view_data_columns.append(column_name)
    
    
    class Specific(Basic):
    
        def __init__(self, some_dict):
            super().__init__(some_dict)
            keys = ['basic_1', 'basic_2']
            for key in keys:
                self.check_for_key_error(key)
    
    
    rem = Specific({})
    
    print(f"missing_keys: {rem.missing_view_data_columns}")
    

    输出:

    missing_keys: [KeyError('basic_1'), KeyError('basic_2'), KeyError('basic_1'), KeyError('basic_2')]

    【讨论】:

      【解决方案3】:

      您确定要存储异常消息吗?因为看起来您只想知道字典中缺少哪些键。如果是这种情况,您应该只查看dictionary.keys()。

      keys_to_look_for = ["key_1", "key_2", "key_n"]
      return [k for k in keys_to_look_for if k not in some_dict.keys()]
      

      您还可以使用dictionary.get() 方法,如果密钥不存在,该方法将返回None。如果失败,您可以设置默认返回值,例如dictionary.get(something, "return this if not found")。但是,这将排除字典中但其值为None 的键。

      return [k for k in keys_to_look_for if not some_dict.get(k)]
      

      【讨论】:

      • 如果key 存在并且其值为None 怎么办?你应该只使用if key in
      猜你喜欢
      • 2021-11-24
      • 1970-01-01
      • 1970-01-01
      • 2016-06-13
      • 2020-12-08
      • 1970-01-01
      • 1970-01-01
      • 2018-07-26
      • 2019-04-01
      相关资源
      最近更新 更多