Mit diesem Code kann ich mein Ziel leider erreichen
a = foo()
a.bar().line().bar().bar().line().my_print()
Aber ich möchte das gleiche Ergebnis erzielen, indem ich diesen Code schreibe
a = foo()
a.bar.line.bar.bar.line.my_print()
Wie erreiche ich das? Ich schätze, etwas stimmt nicht damit, wie ich das definiert habe __call__ Methode. Vielen Dank im Voraus für Ihre Hilfe.
Robᵩ
Methodenverkettung ist einfach hinzufügen zu können .second_func() zu was auch immer .first_func() kehrt zurück. Es ist ziemlich einfach zu implementieren, indem sichergestellt wird, dass alle verkettebaren Methoden zurückgeben self. (Beachte, dass dies nichts zu tun hat mit __call()__).
Da jede Funktion jetzt das Objekt selbst zurückgibt, können Sie direkt mit dem zurückgegebenen Wert arbeiten. Sie können die Methodenverkettung mit diesem entsprechenden Code verwenden:
b = foo()
b.line().my_print().bar().my_print()
assert b.kind == 'bar'
Oder auch:
c = foo().line().my_print().bar().my_print()
assert c.kind == 'bar'
Die Frage, das loszuwerden () Aufrufsyntax ist a völlig separates Konzept aus Methodenketten. Wenn Sie Ketteneigenschaften wünschen und diese Eigenschaften ihr Objekt mutieren lassen, verwenden Sie die @property Dekorateur. (Aber das Mutieren von Objekten über eine Eigenschaft scheint gefährlich. Verwenden Sie besser eine Methode und benennen Sie sie mit einem Verb: .set_line() anstatt .line, zum Beispiel.)
Beachten Sie jedoch, dass Sie nichts überschreiben, die Änderung funktioniert nicht direkt (was übrigens gut ist). Wie auch immer, dies scheint für die meisten realen Fälle keine gute Designwahl zu sein, da Ihre Methoden irgendwann Argumente erfordern.
Es gibt noch einen anderen interessanten Weg, dies zu erreichen
Mit diesem Code musst du nicht bestehen .my_print() Aber eine Sache, die hier zu beachten ist, ist, dass die Foo-Klasse alles als Argument nimmt, wie wenn wir es versuchen print(my_obj.bar.line.bar.bar.circle()) es wird Kreis zurückkehren.
Sie können diesen Code auch bearbeiten, um die Argumente beim Aufrufen einer beliebigen Funktion zu verwenden.