Attribut für Unterklassen von namedtuple kann nicht festgelegt werden

9

Es sieht aus wie dies oder dies sind verwandte Themen, haben aber immer noch nichts herausgefunden:)

Ich versuche, eine Unterklasse von namedtuple zu erstellen und verschiedene Initialisierer bereitzustellen, so dass ich Objekte auf verschiedene Arten konstruieren kann. Zum Beispiel:

%Vor%

Das geht jedoch nicht:

%Vor%

Nach etwas Stöbern (siehe zB dies thread) Ich habe versucht, Konstruktoren anstelle von Initializern zu verwenden:

%Vor%

was ein Objekt zu konstruieren scheint, aber dann kann ich seine Attribute nicht lesen:

%Vor%

Wo gehe ich hier falsch? Wie kann ich eine Unterklasse mit mehreren Konstruktoren oder Initialisierungen erstellen?

    
Jens 08.10.2013, 20:17
quelle

3 Antworten

18

Benannte Tupel sind unveränderlich, daher können Sie sie im Initiator __init__ nicht manipulieren. Ihre einzige Option ist das Überschreiben der Methode __new__ :

%Vor%

Beachten Sie, dass, weil __new__ eine Factory-Methode für neue Instanzen ist, Sie die neu erstellte Instanz zurückgeben müssen. Wenn Sie return nicht in der __new__ -Methode verwenden, lautet der Standard-Rückgabewert None , wodurch Sie den Fehler erhalten.

Demo mit einem Objekt mit den Attributen x und y :

%Vor%

Python unterstützt das Überladen von Methoden nicht; In der Regel verwenden Sie entweder optionale Schlüsselwortargumente oder zusätzliche Klassenmethoden als Factory-Methoden.

Das Modul datetime verfügt beispielsweise über mehrere solcher Factory-Methoden, mit denen Sie Objekte erstellen können die nicht zum Standardkonstruktor passen. datetime.datetime.fromtimestamp() erstellt eine datetime.datetime -Instanz von einem einzelnen numerischen Wert und Dasselbe gilt für datetime.datetime.fromordinal() ; außer dass sie die Zahl auf verschiedene Arten interpretieren.

Wenn Sie variable Argumente unterstützen möchten, tun Sie Folgendes:

%Vor%

Hier ist y ein optionales Argument, das standardmäßig auf None gesetzt wird, wenn es nicht vom Aufrufer bereitgestellt wird:

%Vor%

Die Alternative, die eine Klassenmethode verwendet, wäre:

%Vor%

Jetzt gibt es zwei Fabrikmethoden; ein Standard und ein Name:

%Vor%     
Martijn Pieters 08.10.2013, 20:27
quelle
1

Zwei Dinge: Erstens, du bekommst hier wirklich nicht viel von namedtuple, soweit ich das beurteilen kann. Vielleicht solltest du einfach in eine normale Klasse wechseln. Außerdem können Sie das

nicht überlasten

Zweitens, andere Möglichkeiten, die bei Ihrem Problem helfen könnten:

Factory-Design-Muster - anstatt die verschiedenen Parameter im Konstruktor zu platzieren, muss eine Klasse verschiedene Arten annehmen von Parametern und ruft den Konstruktor mit geeigneten Argumenten außerhalb des Objekts auf. recordtype - ein veränderbares benanntesTuple, das Standardwerte zulässt, aber auch Ihre Unterklasse so schreiben lässt, wie Sie es ursprünglich wollten. Bund - nicht genau ein benanntes Tupel, aber Sie können etwas willkürliche Objekte erstellen.

    
Corley Brigman 08.10.2013 20:57
quelle
0

Es gibt eine Problemumgehung, um das Attribut eines namedtuple zu ändern.

%Vor%     
chahuja 21.06.2016 08:11
quelle