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

  • Richtige Verwendung von PEP 508 Umgebungsmarkierungen in setup.cfg
  • Unterschied zwischen devpi und pypi server
  • Python-Modul nicht gefunden Probleme nach dem Verschieben von Verzeichnis
  • Importieren aus einem Paket in IDLE vs Shell
  • Was ist setup.py?
  •  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?

  • Mit vorgegebenen Keypaar-Tupeln muss ich ein Wörterbuch erstellen
  • Python: Tupel mit variabler Länge
  • Häufigkeitsanalyse mit Tupelfehler
  • Erstellen Sie eine Scheibe mit einem Tupel
  • Python: Wie schreibe ich ein Wörterbuch von Tupel-Werten in eine CSV-Datei?
  • Sortieren eines Wörterbuchs von Tupeln in Python
  • 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.