Gibt es eine Möglichkeit, Klasseninstanzattribute zu erhalten, ohne Klasseninstanz zu erstellen?

Hier ist der Link zu meiner ersten Frage: Erstellen von Klasseninstanz aus dem Wörterbuch?
Also versuche ich, Klasseninstanz aus dem Wörterbuch zu erstellen, das Schlüssel enthält, die Klasse nicht hat. Beispielsweise:

class MyClass(object): def __init__(self, value1, value2): self.attr1 = value1 self.attr2 = value2 dict = {'attr1': 'value1', 'attr2': 'value2', 'redundant_key': 'value3'} 

Vor dem Erstellen der Klasseninstanz muss ich diese redundant_key aus dict löschen

 dict.pop('redundant_key', None) new_instance = MyClass(**dict) 

Das Problem ist, dass ich mehrere Klassen und mehrere Dicts mit vielen Schlüsseln habe (ich habe mehrere Antworten im Json-Format, die als Dicts dargestellt werden und ich will Objekte aus diesen Json-Antworten erstellen). Ich habe schon eine Zwischenlösung aus der vorherigen Frage gefunden – wie man redundante Schlüssel löscht. Ich kann neue dict aus alten dict nur mit schlüssel, die ich brauche:

 new_dict = {key: old_dict[key] for key in allowed_keys} 

Also hier ist der Code:

 class MyClass(object): def __init__(self, value1, value2): self.attr1 = value1 self.attr2 = value2 dict = {'attr1': 'value1', 'attr2': 'value2', 'redundant_key': 'value3'} new_instance = MyClass(**{key: dict[key] for key in allowed_keys}) 

Alles was ich jetzt brauche, bekomme es allowed_keys . Also die Frage – Gibt es irgendeine Möglichkeit, Klasseninstanzattribute zu erhalten, ohne Klasseninstanz zu erstellen?

  • Python: Suchen eines (String) -Taste in einem Wörterbuch, das einen Teilstring enthält
  • Was ist der effizienteste Weg, um Schlüssel von einem Wörterbuch auf Daten in Textdatei abzustimmen
  • Summieren von Python-Objekten mit MPI's Allreduce
  • Karte zwei Listen in ein Wörterbuch in Python
  • Python-Dump-Dict zu json-Datei
  • Anhängen mehrerer Werte für eine Taste im Python-Wörterbuch
  • Arbeiten mit Unicode-Tasten in einem Python-Wörterbuch
  • Löschen von Einträgen in einem Wörterbuch auf der Grundlage einer Bedingung
  • 4 Solutions collect form web for “Gibt es eine Möglichkeit, Klasseninstanzattribute zu erhalten, ohne Klasseninstanz zu erstellen?”

    Wenn Sie darauf bestehen, ein übermäßig allgemeines Wörterbuch zu verwenden, um Ihr Objekt zu initialisieren, definieren __init__ einfach __init__ , um die zusätzlichen Schlüssel zu akzeptieren, aber zu ignorieren.

     class MyClass(object): def __init__(self, attr1, attr2, **kwargs): self.attr1 = attr1 self.attr2 = attr2 d = {'attr1': 'value1', 'attr2': 'value2', 'extra_key': 'value3'} new_instance = MyClass(**d) 

    Wenn Sie __init__ nicht ändern __init__ (wie es der Fall ist, wenn es von einer deklarativen SQLAlchemy-Basis erbt), fügen Sie einen alternativen Konstruktor hinzu, um alle Keyword-Argumente zu akzeptieren, aber wählen Sie die, die Sie benötigen.

     class MyClass(Base): @classmethod def from_dict(cls, **kwargs): # Let any KeyErrors propagate back to the caller. # They're the one who forgot to make sure **kwargs # contained the right keys. value1 = kwargs['attr1'] value2 = kwargs['attr2'] return cls(value1, value2) new_instance = MyClass.from_dict(**d) 

    Haftungsausschluss: Das antwortet, was OP gefragt hat (bekommen Attribute einer Instanz), nicht was sie brauchten. Welches scheint die Parameterliste des Konstruktors zu sein.

    Du kannst nicht tun was du willst. In python-Attributen werden eine Instanz einer Klasse dynamisch hinzugefügt. Zwei Instanzen derselben Klasse können unterschiedliche Attribute haben. Nun … um genau zu sein, gibt es Dinge namens Instanzattribute und Klassenattribute .

    Instanzattribute sind diejenigen, die mit der Instanz einer Klasse verknüpft sind. Klassenattribute sind mit ihrer Definition verbunden, dh wenn Sie ( MyClass.foo )

    Wenn man sich das Beispiel __init__ , werden die Attribute während des __init__ auf sich self hinzugefügt, also sind sie __init__ .

    Was Sie tun können, besteht darin, eine gültige Instanz zu erstellen und zu untersuchen (siehe Beispiel unten), eine statische Liste von allowed_keys (zB als Klassenattribut) zur Verfügung stellen oder in irgendeiner Weise allowed_keys als Konstruktorparameter benötigen. Alle diese sind irgendwelche Workarounds als was Sie wirklich brauchen, ist unmöglich. Sie haben ihre Vor- und Nachteile.

    Beispiel :

     class MyClass(object): def __init__(self, value1, value2): self.attr1 = value1 self.attr2 = value2 instance = MyClass(1,2) # create a valid object instance_attributes = instance.__dict__.keys() # inspect it print(instance_attributes) 

    Hier ist, wie zu tun, was Sie versuchen zu tun: Instantiate Ihre Klassen mit entsprechenden Argumenten. Beachten Sie, dass Sie die Attribute nicht untersuchen, die __init__ erstellt, sondern die Argumente, die es akzeptiert. Es spielt keine Rolle, was es mit ihnen tut – das ist nicht dein Anliegen, wenn du den Konstruktor anrufst.

     myparams = {'attr1': 'value1', 'attr2': 'value2', 'redundant_key': 'value3'} usable = { k:v for k, v in myparams if k in MyClass.__init__.__code__.co_varnames } new_instance = MyClass(**usable) 

    Ich habe ein gefiltertes Wörterbuchverständnis für Klarheit verwendet, aber du kannst es in einem Schritt natürlich machen.

    PS Beachten Sie, dass Sie ein Problem haben werden, wenn eines Ihrer Wörterbücher den Schlüssel self . 🙂 Sie können es filtern, wenn Sie Ihrer Datenquelle nicht vertrauen können.

    Sie sollten erwähnt haben, dass Sie die Spalten einer SQLAlchemy-Mapper-Klasse wollen. Das ist eine viel einfachere Aufgabe:

     dict = {'attr1': 'value1', 'attr2': 'value2', 'redundant_key': 'value3'} columns = YourTable.__table__.columns.keys() entry = YourTable(**{k: dict[k] for k in columns}) 
    Python ist die beste Programmiersprache der Welt.