Wie cast-Objekt in Python
Ich habe zwei Klassen (nennen wir Sie Arbeiten und ReturnStatement), die ich nicht ändern kann, aber ich will verlängern, beide mit Protokollierung. Der trick ist, dass die Arbeiten, die Methode gibt ein ReturnStatement-Objekt, so werden die neuen MutantWorking Objekt gibt auch ReturnStatement es sei denn, ich werfe es MutantReturnStatement. Der Spruch mit code:
# these classes can't be changed
class ReturnStatement(object):
def act(self):
print "I'm a ReturnStatement."
class Working(object):
def do(self):
print "I am Working."
return ReturnStatement()
# these classes should wrap the original ones
class MutantReturnStatement(ReturnStatement):
def act(self):
print "I'm wrapping ReturnStatement."
return ReturnStatement().act()
class MutantWorking(Working):
def do(self):
print "I am wrapping Working."
# !!! this is not working, I'd need that casting working !!!
return (MutantReturnStatement) Working().do()
rs = MutantWorking().do() #I can use MutantWorking just like Working
print "--" # just to separate output
rs.act() #this must be MutantReturnState.act(), I need the overloaded method
Das erwartete Ergebnis:
Ich bin das einwickeln der Arbeit.
Ich bin Arbeiten.
--
Ich bin Umhüllung ReturnStatement.
Ich bin ein ReturnStatement.
Ist es möglich, das problem zu lösen? Ich bin auch gespannt, ob das problem gelöst werden kann, in PHP, auch. Es sei denn, ich bekomme eine funktionierende Lösung, die ich nicht akzeptieren kann, dass die Antwort, so schreiben Sie bitte funktionierenden code zu bekommen, akzeptiert.
Auch sollten Sie es nicht tun "
ReturnStatement().act()
" - wenn Sie möchten, dass die act-Methode ont er anderen Klasse zu arbeiten, um auf das aktuelle Objekt, tun returnStatement.act(self)
- oder markieren Sie es als eine classmethod oder staticmethod - wenn es es nicht nötig, eine Instanz des aktuellen Objektes.Arbeiten.do() kehrt mit einem ReturnStatement. Ich will MutantWorking.tun Sie (), um mit einem MutantReturnStatement. Ich kenne Gießen nicht vorhanden, in Python, aber das problem macht. Gibt es eine Lösung?
Es spielt keine Rolle, ob ich überschreiben MutantReturnStatement die __init__ () - Methode zu tun, die zusätzliche Arbeit und zurück mit einem ReturnStatement oder überschreiben Sie die MutantReturnStatement die act () - Methode, um den job tun, von dem ReturnStatement die act () - Methode. Ich kann Sie nicht erreichen die MutantReturnStatement, weil die Arbeit zurück mit ReturnStatement und nicht mit einem MutantReturnStatement.
InformationsquelleAutor Visko | 2012-02-02
Du musst angemeldet sein, um einen Kommentar abzugeben.
Es ist kein casting wie die anderen Antworten bereits erklärt. Sie können Unterklassen oder stellen geändert, neue Typen mit dem extra an Funktionalität mit Dekorateure.
Hier ist ein vollständiges Beispiel (Kredit Wie eine Kette von Funktion Dekoratoren?). Sie brauchen nicht zu ändern Ihre ursprünglichen Klassen. In meinem Beispiel die original-Klasse aufgerufen wird, zu Arbeiten.
druckt
Außerdem würde ich gerne verstehen, warum können Sie nicht ändern eine Klasse. Hast du das probiert? Denn, wie ein alternative um eine Unterklasse, wenn Sie dynamische fühlen Sie kann fast immer ändern, eine alte Klasse in Ort:
Update: Gelten logging, um alle Methoden einer Klasse
Als Sie nun speziell darum gebeten. Sie kann Schleife über alle Mitglieder und Protokollierung gelten Ihnen allen. Aber Sie brauchen, um eine Regel zu definieren, für welche Art der Mitglieder zu ändern. Das Beispiel unten schließt jede Methode mit __ in seinem Namen .
Mit dieser alles, was Sie tun müssen, um eine neue angemeldet-version der a-Klasse ist:
Oder ändern einer vorhandenen Klasse in Ort:
Nach anfänglicher Begeisterung habe ich leider gemerkt, dass dies nicht eine Lösung für mein problem. Ich kann nicht ändern, die Arbeiterklasse mit Hilfe von Dekoratoren zurück MutantReturnStatement statt ReturnStatement, denn das war die erste Bedingung (die Arbeit kann nicht geändert werden).
Ich denke, dass Sie falsch verstanden, meine Antwort dann. Mein 'loghello' ist genau das 'MutantWorking' Sie gefragt haben. Sie brauchen nicht geändert zu "Arbeiten", gerade als ich nicht ändern "Hallo". Wenn Sie denken, dass dies noch unklar ist, oder wenn Sie nicht damit einverstanden sind, kann ich versuchen, meine Antwort.
Umbenannt habe ich meine Methoden und Klassen zu machen, mehr wie dein Beispiel.
Vielleicht habe ich etwas missverstehen, aber ist es die Rückkehr einer MutantReturnState Objekt? Wenn nicht, ist es nicht eine akzeptable Lösung.
InformationsquelleAutor Johan Lundberg
Gibt es kein "casting" in Python.
Jede Unterklasse von einer Klasse wird als Instanz seiner Eltern. Gewünschte Verhalten erreicht werden kann, durch ordnungsgemäße Berufung die superclass-Methoden, und durch überschreiben der Attribute der Klasse.
Was Sie tun können, auf Ihrem Beispiel, ist eine Unterklasse Initialisierer, erhält der Superklasse und Kopien Ihrer relevanten Attribute - so, Ihr MutantReturnstatement könnte so geschrieben werden:
Und ändern Sie dann Ihre MutantWorking Klasse:
Gibt es Pythonic Möglichkeiten für nicht viel
self.attr = other.attr
Linien auf der__init__
Methode, wenn es viele (wie, mehr als 3 🙂 ) Attributen, die Sie kopieren möchten -die faulsten, die wiuld einfach zu kopieren die andere Instanz ist
__dict__
Attribut.Alternativ wenn Sie wissen, was Sie tun, man könnte auch einfach die
__class__
Attribut des Ziel-Objekt der gewünschten Klasse - aber das kann irreführend sein und führen Sie zu subtilen Fehlern (die__init__
Methode der Unterklasse würde nicht aufgerufen werden, würde nicht funktionieren auf nicht-python-Klassen festgelegt, und andere mögliche Probleme), ich weiß nicht empfehlen Ihnen, dieses Konzept - das ist keine "casting", es ist die Verwendung von Introspektion bruteforce ein Objekt ändern und ist nur enthalten, um zu halten die Antwort abzuschließen:Wieder - sollte dies funktionieren, aber tun Sie es nicht -, verwenden Sie die erste Methode.
Übrigens, ich bin nicht allzu erfahren mit anderen OO-Sprachen, in denen casting -, sondern wirft auch auf eine Unterklasse sogar erlaubt, in irgendeiner Sprache? Macht es Sinn? Ich glaube, casting-s darf nur parentclasses.
ja man kann definieren Sie einen cast von einem Objekt auf ein Objekt in zum Beispiel C++.
Ich muss nicht unbedingt wissen, die nicht-Mutanten-Klassen-Attribute. Lassen Sie uns sagen, Sie sind C++ - Bibliotheken importiert werden, die Python.
InformationsquelleAutor jsbueno
Keinen direkten Weg.
Können Sie definieren, MutantReturnStatement ist init wie diese:
und dann verwenden Sie es wie diese:
Und Sie sollten loswerden zu Erben ReturnStatement in Ihre wrapper, wie diese
Ich mag deine Antwort! Wenn keiner sagt, eine andere (bessere) Technik, ich werde es akzeptieren :).
+1. @Visko, +1, wenn Ihnen etwas gefällt. (Sie können es tun, mehr als einmal.) Auch mit Dekoratoren können Sie dies tun, ohne die Notwendigkeit zu machen, ein solcher code-block, der für jede Methode.
Ich habe nicht Recht noch zu Stimmen (+1) :).
Diese Lösung ist noch nicht perfekt. Ich versäumte zu erwähnen, dass ich brauche MutantWorking muss wieder mit einem MutantReturnStatement die funktioniert fast wie ein ReturnStatement, nur die act () - Methode ist überladen. In dieser Lösung auf die ich zugreifen kann returnStatement als eine Eigenschaft, die ändert die Art, wie ich verwenden können, handeln() (rs.returnStatement.act() anstelle von rs.act() ).
InformationsquelleAutor Jurlie
Brauchen Sie nicht Gießen hier. Sie müssen nur
Natürlich geben die korrekten Absender und der gewünschte Ausdruck.
InformationsquelleAutor Falcon