Spotkałem coś takiego w projekcie open source. Metody modyfikujące atrybuty instancji zwracają odwołanie do instancji. Jaki jest cel tego konstruktu?
class Foo(object):
def __init__(self):
self.myattr = 0
def bar(self):
self.myattr += 1
return self
python
method-chaining
Nate C
źródło
źródło
Odpowiedzi:
Ma to na celu łańcuchowanie.
Na przykład:
Teraz możesz powiedzieć:
źródło
Jak wspominają @Lie Ryan i @Frank Shearar, nazywa się to „płynnym interfejsem”, ale ten wzorzec istnieje już od bardzo dawna.
Kontrowersyjna część tego wzorca jest taka, że w OO masz stan zmienny, więc metoda void ma swego rodzaju domniemaną wartość zwracaną
this
- to znaczy obiekt ze zaktualizowanym stanem jest rodzajem wartości zwracanej.Tak więc w języku OO ze zmiennym stanem te dwa są mniej więcej równoważne:
... w przeciwieństwie do
Więc słyszałem, że ludzie w przeszłości opierali się płynnym interfejsom, ponieważ lubią pierwszą formę. Inną nazwą, którą słyszałem dla „płynnego interfejsu”, jest „wrak pociągu”;)
Mówię „mniej więcej równorzędnie”, ponieważ płynne interfejsy powodują zmarszczki. Nie muszą tego „zwracać”. Mogą „zwrócić nowe”. To sposób na osiągnięcie niezmiennych obiektów w OO.
Więc możesz mieć klasę A, która to robi (pseudokod)
Teraz każda metoda zwraca zupełnie nowy obiekt, pozostawiając początkowy obiekt bez zmian. I to jest sposób na dostanie się do niezmiennych obiektów bez wprowadzania znacznych zmian w kodzie.
źródło
new(...)
, spowoduje to wyciek pamięci.__init__
wielokrotnie wprowadza napowietrznych zbyt.Większość języków jest świadoma idiomu „return self” i ignoruje go, jeśli nie jest używany w wierszu. Warto jednak zauważyć, że w Pythonie funkcje zwracają
None
się domyślnie.Kiedy byłem w szkole CS mój instruktor popełnił ogromny wiele o różnicy między funkcji, procedur, procedur i metod; wiele pytań na temat eseju o skurczach dłoni zostało wyrzuconych z ołówków mechanicznych, które rozgrzały się w moich rękach na ten temat.
Wystarczy powiedzieć, że zwracanie siebie jest ostatecznym sposobem OO do tworzenia metod klas, ale Python pozwala na wiele zwracanych wartości, krotek, list, obiektów, prymitywów lub Brak.
Łańcuchy, jak to ujęli, po prostu przekładają odpowiedź na ostatnią operację na następną, a środowisko wykonawcze Pythona może zoptymalizować tego rodzaju rzeczy. Wyjaśnienia list są wbudowaną formą tego. (Bardzo potężny!)
Tak więc w Pythonie nie jest tak ważne, aby każda metoda lub funkcja zwracała rzeczy, dlatego domyślną wartością jest None.
Istnieje szkoła myślenia, że każda akcja w programie powinna raportować swój sukces, niepowodzenie lub wynik z powrotem do kontekstu lub obiektu wywołującego, ale wtedy nie mówiły tutaj o wymaganiach DOD ADA. Jeśli potrzebujesz informacji zwrotnej na temat metody, śmiało bądź nie, ale staraj się być konsekwentny.
Jeśli metoda może zawieść, powinna zwrócić sukces lub porażkę lub zgłosić wyjątek do obsłużenia.
Jednym zastrzeżeniem jest to, że jeśli użyjesz zwrotnego idiomu, Python pozwoli ci przypisać wszystkie twoje metody do zmiennych i możesz pomyśleć, że otrzymujesz wynik danych lub listę, gdy faktycznie otrzymujesz obiekt.
Języki ograniczające pisanie krzyczą, krzyczą i łamią się, gdy próbujesz to zrobić, ale te interpretowane (Python, Lua, Lisp) są znacznie bardziej dynamiczne.
źródło
W Smalltalk każda metoda, która nie zwraca czegoś jawnie, ma ukryte „powrót siebie”.
Wynika to z faktu, że (a) zwracanie każdej metody powoduje, że model komputerowy jest bardziej jednolity, a (b) bardzo przydatne jest, aby metody zwracały siebie. Josh K podaje dobry przykład.
źródło
Python
, każda metoda, która nie zwraca czegoś jawnie, ma domyślny „return None”.Zalety zwracania obiektu (
return self
)Przykład:
Bardziej popularny styl w społeczności programistów (tak myślę).
Plusy mutowania obiektu (nie
return self
)return
do innych celów.źródło