namedtuple und Standardwerte für optionale Schlüsselwortargumente
Ich versuche zu konvertieren, einem länglichen hohlen "data" - Klasse in eine benannte Tupel. Meine Klasse sieht derzeit ungefähr so aus:
class Node(object):
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right
Nach der Konvertierung zu namedtuple
sieht es so aus:
from collections import namedtuple
Node = namedtuple('Node', 'val left right')
Aber es gibt ein problem hier. Meine ursprüngliche Klasse erlaubt, mich zu übergeben, nur einen Wert und kümmerte sich um den Standard durch die Verwendung von default-Werten für die namens - /keyword-Argumente. So etwas wie:
class BinaryTree(object):
def __init__(self, val):
self.root = Node(val)
Aber das funktioniert nicht, in dem Fall von meinem umgestalteten benannte Tupel, da es von mir, dass pass alle Felder aus. Ich kann natürlich ersetzen die vorkommen von Node(val)
zu Node(val, None, None)
aber es ist nicht nach meinem Geschmack.
So gibt es einen guten trick, die machen meine re-write successful ohne Zugabe eine Menge von code-Komplexität (metaprogramming) oder sollte ich einfach schlucken Sie die Pille und gehen Sie mit der "suchen und ersetzen"? 🙂
InformationsquelleAutor der Frage sasuke | 2012-07-05
Du musst angemeldet sein, um einen Kommentar abzugeben.
Set
Node.__new__.__defaults__
(oderNode.__new__.func_defaults
vor Python 2.6), um die Standard-Werte.Können Sie auch die erforderlichen Felder aus, indem Sie die
__defaults__
Liste kürzer wird.Wrapper
Hier ist eine schöne Hülle für Sie, die können Sie sogar (Optional) legen Sie die Standardwerte auf etwas anderes als
None
. (Dies unterstützt nicht die erforderlichen Argumente.):Beispiel:
InformationsquelleAutor der Antwort Mark Lodato
Ich Unterklassen namedtuple und überschrieb die
__new__
Methode:Dies bewahrt eine intuitive Typ-Hierarchie, die die Schaffung einer factory-Funktion getarnt als Klasse nicht.
InformationsquelleAutor der Antwort justinfay
Wickeln Sie es in eine Funktion aus.
InformationsquelleAutor der Antwort Ignacio Vazquez-Abrams
Mit
eingeben.NamedTuple
in Python 3.6.1+ können Sie sowohl einen Standard-Wert und eine Art Kommentar zu einem NamedTuple Feld. Verwendentyping.Any
wenn Sie nur das erstere:Verwendung:
Auch im Fall, müssen Sie beide default-Werte und optionale Wandelbarkeit, Python 3.7 ist zu haben,Daten-Klassen (PEP 557)dass in einigen (vielen?) Fällen ersetzen namedtuples.
Nebenbei bemerkt: eine Eigenart der aktuellen Spezifikation von Anmerkungen (Ausdrücke nach
:
für Parameter und Variablen und nach->
für die Funktionen) in Python ist, dass Sie bewertet werden bei der Bestimmung der Zeit*. So, da die "class-Namen definiert werden, sobald der gesamte Körper von der Klasse ausgeführt wurde", die Anmerkungen für'Node'
in der Klasse Felder oben müssen strings sein, um zu vermeiden Fehler.Dieser Art geben Hinweise wird als "forward-reference" ([1][2]), und mit PEP 563 Python 3.7+ geht zu einem
__future__
importieren (standardmäßig aktiviert in 4.0), mit denen die vorwärts-Referenzen (ohne Anführungszeichen), die Verschiebung Ihrer Bewertung.* AFAICT nur lokale variable Anmerkungen werden nicht zur Laufzeit ausgewertet. (Quelle: PEP 526)
InformationsquelleAutor der Antwort monk-time
Ich bin mir nicht sicher, ob es eine einfache Möglichkeit mit nur der eingebaute namedtuple. Es ist ein schönes Modul namens recordtypedass diese Funktionalität auf:
InformationsquelleAutor der Antwort jterrace
Dies ist ein Beispiel direkt aus der docs:
So, die OP ' s Beispiel wäre:
Allerdings habe ich wie einige der anderen hier gegebenen Antworten besser. Ich wollte nur hinzufügen, diese auf Vollständigkeit.
InformationsquelleAutor der Antwort Tim Tisdall
Hier ist eine kompaktere version inspiriert von justinfay Antwort:
InformationsquelleAutor der Antwort Gustav Larsson
Ein etwas erweitertes Beispiel zu initialisieren alle fehlenden Argumente mit
None
:InformationsquelleAutor der Antwort Dennis Golomazov
Können Sie auch dieses verwenden:
Diese im Grunde gibt Ihnen die Möglichkeit zu konstruieren, die ein beliebiges benanntes Tupel mit einem default-Wert und überschreiben Sie nur die Parameter, die Sie brauchen, zum Beispiel:
InformationsquelleAutor der Antwort acerisara
Kombination der Ansätze von @Denis und @Mark:
Unterstützen soll erstellen die Tupel mit den positions-Argumenten und auch mit gemischten Fälle.
Testfälle:
aber auch Unterstützung TypeError:
InformationsquelleAutor der Antwort teodor
Kurze, einfache, und nicht dazu führen, Menschen zu verwenden
isinstance
falsch:InformationsquelleAutor der Antwort Elliot Cameron
Finde ich diese version einfacher zu Lesen ist:
Dies ist nicht so effizient, wie es erfordert die Erstellung des Objekts zweimal, aber Sie ändern könnte, dass durch die Definition der Standard-duple innerhalb des Moduls und nur die Funktion haben, die ersetzen-Zeile.
InformationsquelleAutor der Antwort Dave31415
In Python ist3.7+ (zu der Zeit des Schreibens, noch nicht veröffentlicht) es gibt eine neue Standardwerte= Schlüsselwort-argument.
Beispiel:
InformationsquelleAutor der Antwort Anthony Sottile
Hier ist eine weniger flexible, aber präziser version von Mark Lodato wrapper: Es nimmt die Felder und Standardwerte als ein Wörterbuch.
Beispiel:
InformationsquelleAutor der Antwort Li-Wen Yip
Mithilfe der
NamedTuple
Klasse von meinemErweitert Enum (aenum)
Bibliothek, und mit derclass
syntax, dies ist ganz einfach:Den ein potenzieller Nachteil ist die Notwendigkeit, eine
__doc__
string für jedes Attribut mit einem Standardwert (es ist optional für einfache Attribute). Im Einsatz sieht es so aus:Vorteile gegenüber
justinfay Antwort
:ist die Einfachheit, sowie
metaclass
basiert stattexec
basiert.InformationsquelleAutor der Antwort Ethan Furman
Andere Lösung:
Verwendung:
InformationsquelleAutor der Antwort sirex
Inspiriert von diese Antwort auf eine andere Frage, hier ist meine vorgeschlagene Lösung basiert auf einer metaclass und mit
super
(handle Zukunft subcalssing richtig). Es ist ganz ähnlich wie justinfay Antwort.Dann:
InformationsquelleAutor der Antwort Alexey
Da Sie über
namedtuple
als eine Daten-Klasse, die Sie sollten sich bewusst sein, dass python 3.7 die Einführung eines@dataclass
Dekorateur für diese Zwecke-und natürlich hat default-Werte.Ein Beispiel aus den docs:
Viel sauberer, lesbarer und verwendbarer als hacking
namedtuple
. Es ist nicht schwer vorherzusagen, dass die Nutzung vonnamedtuple
s fallen mit der Annahme 3.7.InformationsquelleAutor der Antwort P-Gn