Ich frage mich, ob Python so etwas wie die Funktion für anonyme C # -Klassen hat. Zur Verdeutlichung hier ein Beispiel für ein C # -Schnipsel:
var foo = new { x = 1, y = 2 };
var bar = new { y = 2, x = 1 };
foo.Equals(bar); // "true"
In Python würde ich mir so etwas vorstellen:
foo = record(x = 1, y = 2)
bar = record(y = 2, x = 1)
foo == bar # true
Die spezielle Anforderung besteht darin, ein Objekt mit bestimmten Feldern im Ausdruckskontext erstellen zu können (z. B. in Lambdas und anderen Orten verwendbar, an denen Anweisungen nicht zulässig sind), ohne zusätzliche externe Deklarationen und über das normale Mitglied namentlich auf einzelne Komponenten zugreifen zu können Zugriffssyntax foo.bar. Das erstellte Objekt sollte auch einen strukturellen Vergleich nach Komponentennamen implementieren (nicht nach Position, wie dies bei Tupeln der Fall ist).
Insbesondere: Tupel nicht, weil ihre Komponenten nicht benannt sind; Klassen nicht, weil sie eine Deklaration erfordern; dicts ist es nicht, weil sie unerwünschte foo["bar"]Syntax haben, um auf Komponenten zuzugreifen.
namedtuple ist es nicht, da es auch dann noch einen Namen erfordert, wenn Sie den Typ inline definieren und der Vergleich positionsbasiert und nicht namensbasiert ist. Speziell:
def foo(): return namedtuple("Foo", "x y")(x = 1, y = 2)
def bar(): return namedtuple("Foo", "y x")(x = 1, y = 2)
foo() == bar() # False because fields are compared in order, and not by name
# True would be desired instead
Ich weiß, wie man so etwas bei Bedarf in Python schreibt. Aber ich würde gerne wissen, ob es so etwas in der Python-Standardbibliothek oder in beliebten Bibliotheken von Drittanbietern gibt.
[BEARBEITEN]
Aus diesem Grund gibt es hier eine Lösung mit einem Ausdruck, die zwei sehr informative Antworten von Ken und Alanlcode kombiniert und strukturelle Gleichheit ohne zusätzliche externe Erklärungen ergibt:
type("", (), { \
"__init__": (lambda self, **kwargs: self.__dict__.update(kwargs)), \
"__eq__": (lambda self, other: self.__dict__ == other.__dict__) } \
)(x = 1, y = 2)
Technisch erfüllt es alle Anforderungen der Frage, aber ich hoffe aufrichtig, dass niemand es jemals benutzt (ich werde es definitiv nicht tun).
