Ich möchte eine Klasse erstellen, die eine Liste der in init aufgetretenen Schlüsselfehler speichert.

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}")

Dies ist mein Ansatz, aber es funktioniert nicht. Der folgende Code gibt nur den ersten aufgetretenen Schlüsselfehler aus. Ich kann auch sagen, dass es nicht allzu gut aussieht, weil ich dieselbe Ausnahme zweimal schreiben muss.

Können Sie mir einen Rat geben, wie diese Funktionalität erstellt wird?

0
Beorn 21 Feb. 2020 im 18:31

4 Antworten

Beste Antwort

Sie können Ihr eigenes Wörterbuch implementieren:

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())

Dadurch wird die Wörterbuchinstanz gespeichert und die fehlende Liste Ihrer Klasse aktualisiert, wenn Sie versuchen, auf einen neuen Schlüssel zuzugreifen. Verwenden Sie wie folgt:

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}")

Anzeigen:

missing_keys: ['basic_1', 'basic_2', 'specific_1', 'specific_2']
1
rassar 21 Feb. 2020 im 15:46

Sie könnten das Problem lösen, ohne jemals den Block try/except zu verwenden: Hier ist ein Code, um das zu tun:

class Basic:
    missing_view_data_columns = []

    def __init__(self, some_dict):
        self.some_dict = some_dict

        self.basic_1 = self.some_dict.get('basic_1') or self.add_missing_data_column(KeyError('basic_1'))
        self.basic_2 = self.some_dict.get('basic_1') or self.add_missing_data_column(KeyError('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.get('specific_1') or self.add_missing_data_column(KeyError('specific_1'))
        self.specific_2 = self.some_dict.get('specific_2') or self.add_missing_data_column(KeyError('specific_2'))


rem = Specific({ "specific_1": 1})

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

Hoffe das hilft!

0
Shubham Sharma 21 Feb. 2020 im 16:06

Ich habe Ihren Code so geändert, dass jeder Schlüssel, den Sie überprüfen möchten, durchlaufen wird:

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}")

Ausgabe:

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

1
Dan 21 Feb. 2020 im 15:49

Sind Sie sicher, dass Sie die Ausnahmemeldungen tatsächlich speichern möchten? Weil es so aussieht, als ob Sie nur wissen möchten, welche Schlüssel im Wörterbuch fehlen. Wenn dies der Fall ist, sollten Sie einfach in dictionary.keys () suchen.

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()]

Sie können auch die Methode dictionary.get() verwenden, die None zurückgibt, wenn der Schlüssel nicht vorhanden ist. Sie können einen Standardrückgabewert festlegen, wenn dies fehlschlägt, z. B. dictionary.get(something, "return this if not found"). Dies würde jedoch Schlüssel ausschließen, die sich im Wörterbuch befinden, deren Wert jedoch None ist.

return [k for k in keys_to_look_for if not some_dict.get(k)]
1
AutomaticStatic 21 Feb. 2020 im 16:11