Wie man die Eigenschaft einer Klasse?
In python kann ich hinzufügen, eine Methode zu einer Klasse mit der @classmethod
Dekorateur. Gibt es ein ähnliches Dekorator hinzufügen, um eine Eigenschaft zu einer Klasse? Ich kann besser zeigen, was ich bin reden über.
class Example(object):
the_I = 10
def __init__( self ):
self.an_i = 20
@property
def i( self ):
return self.an_i
def inc_i( self ):
self.an_i += 1
# is this even possible?
@classproperty
def I( cls ):
return cls.the_I
@classmethod
def inc_I( cls ):
cls.the_I += 1
e = Example()
assert e.i == 20
e.inc_i()
assert e.i == 21
assert Example.I == 10
Example.inc_I()
assert Example.I == 11
Ist die syntax, die ich verwendet habe, oben möglich oder würde es erfordern etwas mehr?
Dem Grund will ich die Klasse von Eigenschaften ist, so kann ich lazy load class-Attribute, die scheint vernünftig genug.
Ich weiß nicht, python... ist das die Art von Sachen, die du suchst ? python.org/download/releases/2.2/descrintro/#property
wenn ich lese, dass die Rechte, die Sie erstellen können Methoden zu handeln, wie die setter und getter (wie in anderen Sprachen), so können Sie faul Belastung der Wert der Eigenschaft auf den ersten zu bekommen... ich denke, das ist, was Sie wollten?
Dragon. Die property-Funktion, die Sie suchen, fügt die Eigenschaften zu Instanzen der Klasse, nicht die Klassen selbst. Ich Frage nach
Hier die Lösung zum erstellen von Klassen-Eigenschaft in einem anderen Thema: stackoverflow.com/a/35640842/1113207
Dupe: Mit der Eigenschaft() auf classmethods
wenn ich lese, dass die Rechte, die Sie erstellen können Methoden zu handeln, wie die setter und getter (wie in anderen Sprachen), so können Sie faul Belastung der Wert der Eigenschaft auf den ersten zu bekommen... ich denke, das ist, was Sie wollten?
Dragon. Die property-Funktion, die Sie suchen, fügt die Eigenschaften zu Instanzen der Klasse, nicht die Klassen selbst. Ich Frage nach
Example.I
nicht e.i
.Hier die Lösung zum erstellen von Klassen-Eigenschaft in einem anderen Thema: stackoverflow.com/a/35640842/1113207
Dupe: Mit der Eigenschaft() auf classmethods
InformationsquelleAutor deft_code | 2011-03-04
Du musst angemeldet sein, um einen Kommentar abzugeben.
Hier, wie ich tun würde:
Setter nicht wirklich die Zeit, die wir rufen
Bar.bar
, da wir rufenTypeOfBar.bar.__set__
, die nichtBar.bar.__set__
.Hinzufügen einer Metaklasse definition löst dieses:
Nun alles in Ordnung sein.
die 2. Behauptung hier nicht: drktd.com/6D2b
Scheint nicht funktioniert mit Set.
__set__
nie erhalten, heißt in meinem Beispiel... so könnte ich den Wert meinerclassproperty
die ganze Zeit.. (ich habe nicht ein cetter definiert für meine classproperty)InformationsquelleAutor Mahmoud Abdelkader
Wenn Sie definieren
classproperty
wie folgt, dann ist dein Beispiel funktioniert genau wie gewünscht.Die Einschränkung ist, dass Sie nicht verwenden können, diese für beschreibbare Eigenschaften. Während
e.I = 20
wirft eineAttributeError
,Example.I = 20
wird, überschreiben Sie das property-Objekt selbst.InformationsquelleAutor jchl
Denke ich, können Sie in der Lage sein, dies zu tun mit der Metaklasse. Da die Metaklasse werden kann, wie eine Klasse für die Klasse (wenn das Sinn macht). Ich weiß, Sie können zuweisen einer
__call__()
- Methode der Metaklasse zu überschreiben, ruft die KlasseMyClass()
. Ich Frage mich, wenn Sie mit derproperty
decorator auf die Metaklasse arbeitet ähnlich. (Ich habe nicht versucht dies vor, aber jetzt bin ich neugierig...)[update:]
Wow, es funktioniert:
Hinweis: Dies ist in Python 2.7. Python 3+ verwendet eine andere Technik zu erklären, eine Metaklasse. Verwendung:
class MyClass(metaclass=MetaClass):
entfernen__metaclass__
, und der rest ist die gleiche.Es ist kein Dekorateur, ich bin mir dessen bewusst, dass Sie direkt verwenden können, auf die Klasse, die Sie interessiert sind in. Jedoch, die
property
Dekorator in der Metaklasse funktionieren sollte.... Ich habe bearbeitet meine Antwort zu beinhalten eine eingerichtete Metaklasse Methode.Siehe auch eine ähnliche Frage und seine Antworten. Scheint ähnlich zu sein, so kann es noch einige hilfreiche Informationen 🙂
sehr guter link
Deskriptoren wie
property
werden müssen, in der Art Wörterbuch, um Ihre Magie zu arbeiten. So dass diejenigen, die in der definition einer Klasse betreffen vor allem das Verhalten der Instanzen der Klasse, mit minimalen Auswirkungen auf das Verhalten der Klasse selbst (da die Klasse der Typ der Instanzen). Verschieben der Deskriptoren zu der Metaklasse ermöglicht es Ihnen, um Ihre Magie zu arbeiten auf die Klasse selbst (da die Metaklasse ist der Typ der Klasse).InformationsquelleAutor dappawit
[Antwort geschrieben, basierend auf python 3.4; die Metaklasse syntax unterscheidet sich in 2, aber ich denke, die Technik wird immer noch funktionieren]
Können Sie dies mit einer Metaklasse...meistens. Dappawit ist fast funktioniert, aber ich denke, es hat einen Fehler:
Diese bekommt Sie eine classproperty auf Foo, aber es gibt ein problem...
Was zur Hölle ist hier Los? Warum kann ich nicht erreichen, die Eigenschaft der Klasse, die von einer Instanz?
Ich schlug meinen Kopf auf das für uns schon eine Weile zu finden, was ich glaube, ist die Antwort. Python @Eigenschaften sind eine Untermenge der Deskriptoren, und, von der Deskriptor Dokumentation (Hervorhebung von mir):
Also die Methode, die Auflösung, um nicht auch unsere Klasse von Eigenschaften (oder irgendetwas anderes definiert die Metaklasse). Es ist möglich, eine Unterklasse der built-in-Eigenschaft Dekorateur, verhält sich anders, aber (Zitat benötigt) habe ich mittlerweile den Eindruck googeln, dass die Entwickler hatten einen guten Grund (was ich nicht verstehen), es zu tun auf diese Weise.
Das bedeutet nicht, dass wir Pech gehabt; wir können auf die Eigenschaften, die auf die Klasse an sich ganz gut...und wir erhalten die Klasse von
type(self)
innerhalb der Instanz, die wir nutzen können, um @property Disponenten:Nun
Foo().thingy
funktioniert wie vorgesehen sowohl für die Klasse und den Instanzen! Es wird auch weiterhin das richtige tun, wenn einer abgeleiteten Klasse ersetzt die zugrunde liegende_thingy
(was ist der use case, der hat mich auf diese Jagd ursprünglich).Dies ist nicht 100% befriedigend für mich-mit zu tun, das setup sowohl in der Metaklasse Objekt und Klasse fühlt sich an wie es verstößt gegen das DRY-Prinzip. Aber letzteres ist nur eine one-line-dispatcher; meistens bin ich in Ordnung mit ihm bestehenden, und wahrscheinlich könnten Sie kompakt bis zu einer lambda oder etwas, wenn Sie wirklich wollte.
InformationsquelleAutor Andrew
Soweit ich das beurteilen kann, gibt es keine Möglichkeit, schreiben einen setter für Eigenschaft einer Klasse, ohne eine neue Metaklasse.
Habe ich festgestellt, dass die folgende Methode funktioniert. Definieren Sie eine Metaklasse, die mit allen Eigenschaften der Klasse und setter, die Sie wollen. SPRICH, ich wollte eine Klasse mit einer
title
Eigenschaft mit einem setter. Hier ist, was ich schrieb:Nun die eigentliche Klasse, die Sie wollen, wie normal, außer es haben, verwenden Sie die Metaklasse, die Sie oben erstellt.
Es ist ein bisschen seltsam zu definieren, die dieser Metaklasse, wie oben beschrieben, wenn wir nur jemals verwenden Sie es auf die einzelne Klasse. In diesem Fall, wenn Sie den Python-2-Stil, können Sie tatsächlich definieren die metaclass innerhalb der Klasse Körper. So ist es nicht im Modul definierten Umfang.
InformationsquelleAutor ArtOfWarfare
Wenn Sie nur brauchen, lazy loading, dann könnten Sie einfach einen Klassen-Initialisierungs-Methode.
Aber die Metaklasse Ansatz scheint sauberer und mit mehr vorhersagbaren Verhalten.
Vielleicht, was du suchst, ist die Singleton design-Muster. Es gibt einen schönen SO QA über die Implementierung von shared state in Python.
InformationsquelleAutor Apalala
Ich hatte zu kommen mit einer Lösung, sehr ähnlich wie @Andreas, nur TROCKEN
Dieser hat die beste aller Antworten:
Den "meta-Eigenschaft" ist Hinzugefügt, um die Klasse, so, dass es noch eine Eigenschaft der Instanz
In meinem Fall, habe ich eigentlich angepasst
_thingy
anders sein für jedes Kind, ohne es zu definieren in jeder Klasse (und ohne default-Wert) von:InformationsquelleAutor Andy