python example - Unterschied zwischen __str__ und __repr__?




__add__ vs (18)

Von http://pyref.infogami.com/__str__ durch effbot:

__str__ "berechnet die" informelle "Zeichenfolgendarstellung eines Objekts. Dies unterscheidet sich von __repr__ dass es sich nicht um einen gültigen Python-Ausdruck handeln muss. Stattdessen kann eine bequemere oder prägnantere Darstellung verwendet werden."

Was ist der Unterschied zwischen __str__ und __repr__ in Python ?


Was ist der Unterschied zwischen __str__ und __repr__ in Python?

__str__ (gelesen als "dunder (doppelter Unterstrich) - String") und __repr__ (gelesen als "dunder-repper" (für "Darstellung")) sind beide spezielle Methoden, die Strings basierend auf dem Status des Objekts zurückgeben.

__repr__ gibt das Sicherungsverhalten an, wenn __str__ fehlt.

Daher sollte man zuerst ein __repr__ schreiben, mit dem ein äquivalentes Objekt aus der zurückgegebenen Zeichenfolge __repr__ kann, z. B. mit eval oder durch Eingabe von Zeichen für Zeichen in einer Python-Shell.

Zu einem späteren Zeitpunkt kann ein __str__ für eine vom Benutzer lesbare Zeichenfolgendarstellung der Instanz geschrieben werden, wenn dies als notwendig erachtet wird.

__str__

Wenn Sie ein Objekt drucken oder an format , str.format oder str , wird diese Methode aufgerufen, wenn eine __str__ Methode definiert ist. Andernfalls wird __repr__ verwendet.

__repr__

Die __repr__ Methode wird von der eingebauten Funktion repr aufgerufen und wird in Ihrer Python-Shell angezeigt, wenn sie einen Ausdruck auswertet, der ein Objekt zurückgibt.

Da es eine Sicherung für __str__ bietet, beginnen Sie mit __repr__ , wenn Sie nur eine schreiben __repr__

Hier ist die eingebaute Hilfe zu repr :

repr(...)
    repr(object) -> string

    Return the canonical string representation of the object.
    For most object types, eval(repr(object)) == object.

Das heißt, für die meisten Objekte sollten Sie in der Lage sein, ein gleichwertiges Objekt zu erstellen, wenn Sie repr , was von repr gedruckt wird. Dies ist jedoch nicht die Standardimplementierung.

Standardimplementierung von __repr__

Das Standardobjekt __repr__ lautet ( C-Python-Quelle ), etwa wie __repr__ :

def __repr__(self):
    return '<{0}.{1} object at {2}>'.format(
      self.__module__, type(self).__name__, hex(id(self)))

Das bedeutet, dass Sie standardmäßig das Modul drucken, aus dem sich das Objekt befindet, den Klassennamen und die hexadezimale Darstellung des Speicherorts im Speicher, z. B .:

<__main__.Foo object at 0x7f80665abdd0>

Diese Informationen sind nicht sehr nützlich, aber man kann nicht ableiten, wie man eine kanonische Repräsentation einer bestimmten Instanz genau erzeugen kann, und es ist besser als nichts, zumindest uns zu sagen, wie wir sie im Speicher eindeutig identifizieren können.

Wie kann __repr__ nützlich sein?

Schauen wir uns an, wie nützlich es ist, wenn man die Python-Shell und die datetime Objekte verwendet. Zuerst müssen wir das datetime Modul importieren:

import datetime

Wenn wir datetime.now in der Shell aufrufen, sehen wir alles, was wir benötigen, um ein entsprechendes datetime-Objekt neu zu erstellen. Dies wird durch die Datumszeit __repr__ :

>>> datetime.datetime.now()
datetime.datetime(2015, 1, 24, 20, 5, 36, 491180)

Wenn wir ein datetime-Objekt drucken, sehen wir ein schönes, vom Menschen lesbares Format (tatsächlich ISO). Dies wird durch __str__ von datetime __str__ :

>>> print(datetime.datetime.now())
2015-01-24 20:05:44.977951

Es ist eine einfache Sache, das verlorene Objekt neu zu erstellen, weil wir es keiner Variablen zugewiesen haben, indem es aus der __repr__ Ausgabe kopiert und __repr__ wurde. Anschließend wurde es gedruckt, und wir erhalten es in derselben vom Menschen lesbaren Ausgabe wie das andere Objekt:

>>> the_past = datetime.datetime(2015, 1, 24, 20, 5, 36, 491180)
>>> print(the_past)
2015-01-24 20:05:36.491180

Wie implementiere ich sie?

Bei der Entwicklung sollten Sie Objekte möglichst im gleichen Zustand reproduzieren können. So definiert das datetime-Objekt beispielsweise __repr__ ( Python-Quelle ). Es ist ziemlich komplex, da alle Attribute zur Wiedergabe eines solchen Objekts erforderlich sind:

def __repr__(self):
    """Convert to formal string, for repr()."""
    L = [self._year, self._month, self._day, # These are never zero
         self._hour, self._minute, self._second, self._microsecond]
    if L[-1] == 0:
        del L[-1]
    if L[-1] == 0:
        del L[-1]
    s = ", ".join(map(str, L))
    s = "%s(%s)" % ('datetime.' + self.__class__.__name__, s)
    if self._tzinfo is not None:
        assert s[-1:] == ")"
        s = s[:-1] + ", tzinfo=%r" % self._tzinfo + ")"
    return s

Wenn Sie möchten, dass Ihr Objekt besser lesbar ist, können __str__ Nächstes __str__ implementieren. Das datetime-Objekt ( Python-Quelle ) implementiert __str__ ist einfach möglich, da es bereits über eine Funktion zur Anzeige im ISO-Format verfügt:

def __str__(self):
    "Convert to string, for str()."
    return self.isoformat(sep=' ')

Setze __repr__ = __str__ ?

Dies ist eine Kritik einer anderen Antwort, die die Einstellung von __repr__ = __str__ .

Die Einstellung __repr__ = __str__ ist dumm - __repr__ ist ein Fallback für __str__ und ein __repr__ , das für Entwickler in Debugging- __repr__ geschrieben wurde, sollte vor dem Schreiben eines __str__ .

Sie benötigen ein __str__ nur, wenn Sie eine Textdarstellung des Objekts benötigen.

Fazit

Definieren Sie __repr__ für Objekte, die Sie schreiben, damit Sie und andere Entwickler bei der Entwicklung ein reproduzierbares Beispiel erhalten. Definieren Sie __str__ wenn Sie eine für Menschen lesbare Zeichenfolgendarstellung benötigen.


Wenn Sie nicht ausdrücklich etwas anderes tun, haben die meisten Klassen keine hilfreichen Ergebnisse für:

>>> class Sic(object): pass
... 
>>> print str(Sic())
<__main__.Sic object at 0x8b7d0>
>>> print repr(Sic())
<__main__.Sic object at 0x8b7d0>
>>> 

Wie Sie sehen - kein Unterschied und keine Informationen außerhalb der Klassen- und Objekt- id . Wenn Sie nur eine der beiden Einstellungen überschreiben ...:

>>> class Sic(object): 
...   def __repr__(object): return 'foo'
... 
>>> print str(Sic())
foo
>>> print repr(Sic())
foo
>>> class Sic(object):
...   def __str__(object): return 'foo'
... 
>>> print str(Sic())
foo
>>> print repr(Sic())
<__main__.Sic object at 0x2617f0>
>>> 

Wie Sie sehen, wenn Sie __repr__ überschreiben, wird dies auch für __str__ , nicht jedoch umgekehrt.

Weitere wichtige __str__ : __str__ in einem eingebauten Container verwendet __repr__ , NICHT __str__ für die darin enthaltenen Elemente. Und trotz der Wörter zum Thema, die in typischen Dokumenten zu finden sind, __repr__ kaum jemand, dass __repr__ von Objekten eine Zeichenfolge ist, die eval zum Erstellen eines gleichwertigen Objekts verwendet (es ist einfach zu schwer, UND nicht zu wissen, wie das betreffende Modul tatsächlich importiert wurde es ist eigentlich völlig unmöglich).

Mein Rat: Fokussieren Sie sich darauf, __str__ einigermaßen lesbar zu machen und __repr__ so eindeutig wie möglich zu machen, selbst wenn dies das unscharfe, unerreichbare Ziel __repr__ , __repr__ Rückgabewert als Eingabe für __eval__ akzeptabel zu __eval__ !


__str__ und __repr__ intuitiv und dauerhaft zu verstehen.

__str__ den als Zeichenfolge getarnten Körper eines gegebenen Objekts für die Lesbarkeit der Augen zurück
__repr__ den realen Fleischkörper eines gegebenen Objekts zurückgeben (selbst zurückgeben), um die Eindeutigkeit zu identifizieren.

Sehen Sie es in einem Beispiel

In [30]: str(datetime.datetime.now())
Out[30]: '2017-12-07 15:41:14.002752'
Disguised in string form

Zu __repr__

In [32]: datetime.datetime.now()
Out[32]: datetime.datetime(2017, 12, 7, 15, 43, 27, 297769)
Presence in real body which allows to be manipulated directly.

Wir können arithmetische Operationen mit __repr__ Ergebnissen bequem durchführen.

In [33]: datetime.datetime.now()
Out[33]: datetime.datetime(2017, 12, 7, 15, 47, 9, 741521)
In [34]: datetime.datetime(2017, 12, 7, 15, 47, 9, 741521) - datetime.datetime(2
    ...: 017, 12, 7, 15, 43, 27, 297769)
Out[34]: datetime.timedelta(0, 222, 443752)

Wenn die Operation auf __str__

In [35]: '2017-12-07 15:43:14.002752' - '2017-12-07 15:41:14.002752'
TypeError: unsupported operand type(s) for -: 'str' and 'str'

Gibt nur einen Fehler zurück.

Ein anderes Beispiel.

In [36]: str('string_body')
Out[36]: 'string_body' # in string form

In [37]: repr('real_body')
Out[37]: "'real_body'" #its real body hide inside

Ich hoffe, dies hilft Ihnen dabei, konkrete Gründe zu finden, um weitere Antworten zu finden.


Ein Aspekt, der in anderen Antworten fehlt. Es stimmt, dass das Muster im Allgemeinen lautet:

  • Ziel von __str__ : für Menschen lesbar
  • Ziel von __repr__ : eindeutig, evtl. maschinenlesbar

Leider ist diese Unterscheidung fehlerhaft, da Python REPL und auch IPython __repr__ für das Drucken von Objekten in einer REPL-Konsole verwenden (siehe verwandte Fragen zu Python und IPython ). Daher haben Projekte, die auf interaktive Konsolenarbeit abzielen (z. B. Numpy oder Pandas), damit begonnen, die obigen Regeln zu ignorieren und stattdessen eine von Menschen lesbare __repr__ Implementierung __repr__ .


Meine Faustregel: __repr__ gilt für Entwickler, __str__ für Kunden.


Abgesehen von allen Antworten möchte ich noch einige Punkte hinzufügen: -

1) __repr__() wird aufgerufen, wenn Sie einfach den Namen des Objekts in die interaktive Python-Konsole schreiben und die Eingabetaste drücken.

2) __str__() wird aufgerufen, wenn Sie ein Objekt mit der __str__() verwenden.

3) Falls __str__ fehlt, dann print und jede Funktion, die str() ruft __repr__() des Objekts auf.

4) __str__() von Containern führt bei Aufruf die __repr__() Methode der enthaltenen Elemente aus.

5) str() das innerhalb von __str__() aufgerufen wird, könnte möglicherweise ohne Basisfall erneut auftreten und Fehler bei der maximalen Rekursionstiefe.

6) __repr__() kann repr() aufrufen, um automatisch eine unendliche Rekursion zu vermeiden, wobei ein bereits dargestelltes Objekt durch ... .


Kurz gesagt, das Ziel von __repr__ ist eindeutig und __str__ lesbar.

Hier ist ein gutes Beispiel:

>>> import datetime
>>> today = datetime.datetime.now()
>>> str(today)
'2012-03-14 09:21:58.130922'
>>> repr(today)
'datetime.datetime(2012, 3, 14, 9, 21, 58, 130922)'

Lesen Sie diese Dokumentation für repr:

repr(object)

Gibt eine Zeichenfolge zurück, die eine druckbare Darstellung eines Objekts enthält. Dies ist derselbe Wert, der sich aus Conversions ergibt (umgekehrte Quotes). Es ist manchmal nützlich, auf diesen Vorgang als gewöhnliche Funktion zugreifen zu können. Bei vielen Typen versucht diese Funktion, eine Zeichenfolge zurückzugeben, die ein Objekt mit demselben Wert ergibt, wenn sie an eval() wird. Andernfalls handelt es sich bei der Darstellung um eine in spitze Klammern eingeschlossene Zeichenfolge, die den Namen des Objekttyps enthält mit zusätzlichen Informationen, die häufig den Namen und die Adresse des Objekts enthalten. Eine Klasse kann steuern, was diese Funktion für ihre Instanzen zurückgibt, indem sie eine __repr__() Methode definiert.

Hier ist die Dokumentation für str:

str(object='')

Gibt eine Zeichenfolge zurück, die eine schön druckbare Darstellung eines Objekts enthält. Bei Strings wird der String selbst zurückgegeben. Der Unterschied zu repr(object) besteht darin, dass str(object) nicht immer versucht, eine Zeichenfolge zurückzugeben, die für eval() zulässig ist. Sein Ziel ist es, eine druckbare Zeichenfolge zurückzugeben. Wenn kein Argument angegeben ist, wird die leere Zeichenfolge '' .


>>> print(decimal.Decimal(23) / decimal.Decimal("1.05"))
21.90476190476190476190476190
>>> decimal.Decimal(23) / decimal.Decimal("1.05")
Decimal('21.90476190476190476190476190')

Wenn print () nach dem Ergebnis von decimal.Decimal (23) / decimal.Decimal ("1.05") aufgerufen wird, wird die Rohzahl gedruckt. Diese Ausgabe erfolgt in einer String-Form, die mit __str __ () erreicht werden kann. Wenn wir einfach den Ausdruck eingeben, erhalten wir eine dezimale.Decimal-Ausgabe - diese Ausgabe hat eine repräsentative Form, die mit __repr __ () erreicht werden kann. Alle Python-Objekte haben zwei Ausgabeformen. Die String-Form ist für Menschen lesbar. Die Darstellungsform soll eine Ausgabe erzeugen, die, wenn sie einem Python-Interpreter zugeführt wird, (wenn möglich) das dargestellte Objekt erneut erzeugen würde


"A basic requirement for a Python object is to provide usable 
 string   representations of itself, one used for debugging and
 logging, another for presentation to end users. That is why the  
 special methods __repr__ and __str__ exist in the data model."

Aus dem Buch: Fließender Python


Alex fasste gut zusammen, war aber überraschend zu knapp.

Lassen Sie mich zunächst die wichtigsten Punkte in Alex 'Beitrag wiederholen:

  • Die Standardimplementierung ist unbrauchbar (es ist schwer vorstellbar, welche nicht wäre, aber ja)
  • Ziel ist es, eindeutig zu sein
  • __str__ Ziel ist es, lesbar zu sein
  • Container __str__ verwendet enthaltene Objekte ' __repr__

Die Standardimplementierung ist nutzlos

Dies ist meistens eine Überraschung, da die Standardeinstellungen von Python ziemlich nützlich sind. In diesem Fall haben Sie jedoch einen Standardwert für __repr__ der folgendermaßen __repr__ würde:

return "%s(%r)" % (self.__class__, self.__dict__)

wäre zu gefährlich gewesen (z. B. zu einfach, um in eine unendliche Rekursion zu gelangen, wenn sich Objekte auf einander beziehen). Also macht Python Cops raus. Beachten Sie, dass es einen Standard gibt, der wahr ist: Wenn __repr__ definiert ist und __str__ nicht, verhält sich das Objekt wie __str__=__repr__ .

In einfachen Worten bedeutet dies: Fast jedes Objekt, das Sie implementieren, sollte über eine funktionale __repr__ , die für das Verständnis des Objekts __repr__ . Die Implementierung von __str__ ist optional: Tun Sie dies, wenn Sie eine " __str__ Print" -Funktionalität benötigen (z. B. von einem Berichtsgenerator verwendet).

Das Ziel von __repr__ ist es, eindeutig zu sein

Lassen Sie mich gleich rauskommen und es sagen - ich glaube nicht an Debugger. Ich weiß nicht wirklich, wie man einen Debugger benutzt, und ich habe noch nie einen ernsthaften verwendet. Darüber hinaus glaube ich, dass der große Fehler bei Debuggern ihre grundlegende Natur ist - die meisten Fehler, die ich debuggen konnte, sind vor langer Zeit in einer weit entfernten Galaxie aufgetreten. Dies bedeutet, dass ich mit religiösem Eifer an den Holzeinschlag glaube. Protokollierung ist das Lebenselixier eines anständigen Fire-and-Forget-Serversystems. Python vereinfacht das Protokollieren: Mit möglicherweise einigen projektspezifischen Wrappern benötigen Sie lediglich eine

log(INFO, "I am in the weird function and a is", a, "and b is", b, "but I got a null C — using default", default_c)

Aber Sie müssen den letzten Schritt tun - stellen Sie sicher, dass jedes Objekt, das Sie implementieren, über einen nützlichen Repräsentanten verfügt, sodass Code wie dieser einfach funktioniert. Deshalb kommt die Sache "eval" zum Vorschein: Wenn Sie genügend Informationen haben, dann eval(repr(c))==c , dann wissen Sie alles über c . Wenn das leicht genug ist, zumindest auf unscharfe Weise, dann machen Sie es. Wenn nicht, stellen Sie sicher, dass Sie über genügend Informationen zu c verfügen. Normalerweise verwende ich ein eval-ähnliches Format: "MyClass(this=%r,that=%r)" % (self.this,self.that) . Dies bedeutet nicht, dass Sie MyClass tatsächlich erstellen können, oder dass dies die richtigen Konstruktorargumente sind - aber es ist eine nützliche Form, um auszudrücken: "Dies ist alles, was Sie über diese Instanz wissen müssen".

Hinweis: Ich habe %r oben verwendet, nicht %s . Sie möchten immer repr() [oder %r Formatierungszeichen, äquivalent] in der __repr__ Implementierung verwenden, oder Sie vereiteln das Ziel des Repros. Sie möchten MyClass(3) und MyClass("3") .

Das Ziel von __str__ ist es, lesbar zu sein

Insbesondere soll es nicht eindeutig sein - beachten Sie, dass str(3)==str("3") . Wenn Sie eine IP-Abstraktion implementieren, ist es genauso gut, wenn die Zeichenfolge 192.168.1.1 angezeigt wird. Bei der Implementierung einer Datums- / Zeitabstraktion kann der str "2010/4/12 15:35:22" usw. sein. Das Ziel ist es, sie so darzustellen, dass ein Benutzer und kein Programmierer sie lesen möchte. Hacken Sie unnötige Ziffern ab, geben Sie vor, eine andere Klasse zu sein - solange es die Lesbarkeit unterstützt, ist es eine Verbesserung.

Container __str__ verwendet enthaltene Objekte ' __repr__

Das scheint überraschend zu sein, nicht wahr? Es ist ein wenig, aber wie wäre es lesbar

[moshe is, 3, hello
world, this is a list, oh I don't know, containing just 4 elements]

Sein? Nicht sehr. Insbesondere für die Zeichenfolgen in einem Container wäre es viel zu leicht, die Zeichenfolgendarstellung zu stören. Denken Sie daran, dass sich Python angesichts der Mehrdeutigkeit der Versuchung widersetzt, zu raten. Wenn Sie das obige Verhalten beim Drucken einer Liste wünschen, einfach

print "[" + ", ".join(l) + "]"

(Sie können wahrscheinlich auch herausfinden, was mit Wörterbüchern zu tun ist.

Zusammenfassung

Implementieren Sie __repr__ für jede Klasse, die Sie implementieren. Dies sollte eine zweite Natur sein. Implementieren Sie __str__ wenn Sie der Meinung sind, dass es sinnvoll ist, eine String-Version zu verwenden, die der besseren Lesbarkeit __str__ mehr Mehrdeutigkeit bietet.


Ausgezeichnete Antworten decken bereits den Unterschied zwischen __str__ und __repr__ , was für mich darauf __repr__ , dass erstere sogar für einen Endbenutzer lesbar sind und letztere für Entwickler so nützlich wie möglich ist. In Anbetracht dessen finde ich, dass die Standardimplementierung von __repr__ dieses Ziel häufig nicht erreicht, da für Entwickler nützliche Informationen __repr__ .

Aus diesem Grund versuche ich, wenn ich ein einfaches genug __str__ , im Allgemeinen nur das Beste aus beiden Welten mit etwas wie:

def __repr__(self):
    return '{0} ({1})'.format(object.__repr__(self), str(self))

Einfach gesagt:

__str__ wird verwendet, um eine Zeichenfolgendarstellung Ihres Objekts __str__ , die von anderen leicht gelesen werden kann .

__repr__ wird verwendet, um eine Zeichenfolgendarstellung des Objekts __repr__ .

Nehmen wir an, ich möchte eine Fraction Klasse erstellen, bei der die Zeichenfolgendarstellung eines Bruchs '(1/2)' ist und das Objekt (Fraction-Klasse) als 'Fraction (1,2)' dargestellt werden soll.

So können wir eine einfache Fraktionsklasse erstellen:

class Fraction:
    def __init__(self, num, den):
        self.__num = num
        self.__den = den

    def __str__(self):
        return '(' + str(self.__num) + '/' + str(self.__den) + ')'

    def __repr__(self):
        return 'Fraction (' + str(self.__num) + ',' + str(self.__den) + ')'



f = Fraction(1,2)
print('I want to represent the Fraction STRING as ' + str(f)) # (1/2)
print('I want to represent the Fraction OBJECT as ', repr(f)) # Fraction (1,2)

In einer Nussschale:

class Demo:
  def __repr__(self):
    return 'repr'
  def __str__(self):
    return 'str'

demo = Demo()
print(demo) # use __str__, output 'str' to stdout

s = str(demo) # __str__ is used, return 'str'
r = repr(demo) # __repr__ is used, return 'repr'

import logging
logger = logging.getLogger(logging.INFO)
logger.info(demo) # use __str__, output 'str' to stdout

from pprint import pprint, pformat
pprint(demo) # use __repr__, output 'repr' to stdout
result = pformat(demo) # use __repr__, result is string which value is 'str'

Auf Seite 358 des Buches Python-Scripting für Computerwissenschaft von Hans Petter Langtangen heißt es klar

  • Das __repr__ zielt auf eine vollständige Darstellung des Objekts in einer Zeichenkette.
  • Die __str__ gibt eine __str__ Zeichenfolge zum Drucken zurück.

Ich bevorzuge es, sie als zu verstehen

  • repr = reproduzieren
  • str = string (Darstellung)

Aus der Sicht des Benutzers, obwohl dies ein Missverständnis ist, das ich beim Lernen von Python gemacht habe.

Ein kleines, aber gutes Beispiel wird auf derselben Seite wie folgt gegeben:

Beispiel

In [38]: str('s')
Out[38]: 's'

In [39]: repr('s')
Out[39]: "'s'"

In [40]: eval(str('s'))
Traceback (most recent call last):

  File "<ipython-input-40-abd46c0c43e7>", line 1, in <module>
    eval(str('s'))

  File "<string>", line 1, in <module>

NameError: name 's' is not defined


In [41]: eval(repr('s'))
Out[41]: 's'

So viel klarer aus dem blog

str ist wie toString. erstellt, so dass Sie die Daten drucken können, wie Serialisierung oder Pickle. Wie kann ich dieses Objekt neu erstellen, wenn ich dies mit eval () tun muss?

>>> import datetime
>>> now = datetime.datetime.now() 
>>> str(now)
'2015-04-04 20:51:31.766862'
>>> repr(now)
'datetime.datetime(2015, 4, 4, 20, 51, 31, 766862)'
>>mydate = eval(repr(now))

__repr__ : Die Darstellung eines Python-Objekts konvertiert es normalerweise in dieses Objekt zurück

__str__ : ist das, was Sie als Objekt in Textform halten

z.B

>>> s="""w'o"w"""
>>> repr(s)
'\'w\\\'o"w\''
>>> str(s)
'w\'o"w'
>>> eval(str(s))==s
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1
    w'o"w
       ^
SyntaxError: EOL while scanning single-quoted string
>>> eval(repr(s))==s
True

Ich denke, dass die ONLamp-Einführung in die Metaklassen-Programmierung gut geschrieben ist und eine sehr gute Einführung in das Thema gibt, obwohl sie bereits mehrere Jahre alt ist.

http://www.onlamp.com/pub/a/python/2003/04/17/metaclasses.html (archiviert unter https://web.archive.org/web/20080206005253/http://www.onlamp.com/pub/a/python/2003/04/17/metaclasses.html )

Kurz gesagt: Eine Klasse ist ein Bauplan für die Erstellung einer Instanz, eine Metaklasse ist ein Bauplan für die Erstellung einer Klasse. Es ist leicht zu erkennen, dass Klassen in Python auch erstklassige Objekte sein müssen, um dieses Verhalten zu ermöglichen.

Ich habe selbst noch nie eine geschrieben, aber ich denke, eine der schönsten Anwendungen von Metaklassen kann im Django-Framework gesehen werden . Die Modellklassen verwenden einen Metaklassen-Ansatz, um eine deklarative Schreibweise für neue Modelle oder Formularklassen zu ermöglichen. Während die Metaklasse die Klasse erstellt, haben alle Mitglieder die Möglichkeit, die Klasse selbst anzupassen.

Was Sie noch zu sagen haben: Wenn Sie nicht wissen, was Metaklassen sind, ist die Wahrscheinlichkeit, dass Sie sie nicht benötigen, 99%.





python magic-methods repr