Hinzufügen von Attributen zu Instanzmethoden in Python

8

Ich möchte einer Instanzmethode in einer meiner Klassen ein Attribut hinzufügen. Ich versuchte die Antwort in diese Frage , aber diese Antwort funktioniert nur für Funktionen - soweit ich das beurteilen kann.

Als Beispiel möchte ich etwas tun können wie:

%Vor%

Aber wenn ich foo (). bar () anrufe, bekomme ich:

%Vor%

Mein Ziel dabei ist, zu versuchen, zu beeindrucken, dass die Variable 'counter' lokal für die bar () -Methode ist, und um zu vermeiden, dass mein Klassennamespace mit einem anderen Attribut überfüllt wird. Gibt es eine Möglichkeit, dies zu tun? Gibt es eine mehr pythische Art, dies zu tun?

    
sbell 01.03.2012, 20:17
quelle

4 Antworten

8

In Python 3 würde Ihr Code funktionieren, aber in Python 2 gibt es ein Wrapping, das stattfindet, wenn Methoden nachgeschlagen werden.

Klasse vs Instanz

  • klasse level: das Speichern von counter mit der Funktion (entweder direkt oder mit einem veränderbaren Standard) macht es effektiv zu einem Attribut auf Klassenebene, da es immer nur eine Funktion gibt, egal wie viele Instanzen Sie haben haben (sie alle teilen sich das gleiche Funktionsobjekt).

  • Instanz-Level: Um counter zu einem Instanz-Level-Attribut zu machen, müssen Sie die Funktion in __init__ erstellen und dann mit functools.partial umhüllen (so verhält es sich wie eine normale Methode) und dann speichern auf der Instanz - jetzt haben Sie für jede Instanz ein Funktionsobjekt.

Klassenstufe

Die akzeptierte Vorgehensweise für eine statisch-ähnliche Variable besteht darin, ein veränderbares Standardargument zu verwenden:

%Vor%

Wenn Sie wollen, dass es hübscher wird, können Sie Ihren eigenen veränderbaren Behälter definieren:

%Vor%

und ändern Sie Ihren Code wie folgt:

%Vor%

Instanz-Ebene

%Vor%

Zusammenfassung

Wie Sie sehen, wurde die Lesbarkeit beim Übergang zur Instanzebene für counter stark beeinträchtigt. Ich schlage vor, dass Sie die Wichtigkeit betonen, dass counter Teil von bar ist und wenn es wirklich wichtig ist, bar zu einer eigenen Klasse zu machen, deren Instanzen Teil der Instanzen von foo werden. Wenn es nicht wirklich wichtig ist, mach es wie üblich:

%Vor%     
Ethan Furman 01.03.2012, 20:52
quelle
2

Es tut mir leid, einen älteren Post zu finden, aber ich habe ihn bei meinen Suchen gefunden und tatsächlich jemanden mit einer Lösung gefunden.

Hier ist ein Blogbeitrag, der das Problem beschreibt, das Sie haben, und wie Sie einen Dekorateur erstellen, der das tut, was Sie wollen. Sie erhalten nicht nur die Funktionalität, die Sie benötigen, sondern der Autor erklärt auch, warum Python so funktioniert.

Ссылка

    
ElementalVoid 26.12.2012 17:57
quelle
0

Sie benötigen eine Methode __init__ , um das Datenelement zu initialisieren:

%Vor%

Das direkte Anhängen von Daten an Funktionen ist eindeutig nicht pythonisch.

    
Greg Hewgill 01.03.2012 20:19
quelle
0

Wenn der Zähler für alle Instanzen persistent sein soll, können Sie Folgendes tun: Dies ist immer noch nicht Pythonic.

%Vor%     
Wessie 01.03.2012 20:35
quelle