Podczas pisania przypadkowych tematów na temat oprogramowania online natknąłem się na pisanie kaczek i nie do końca go rozumiałem.
Co to jest „pisanie kaczek”?
programming-languages
duck-typing
Sushil Bharwani
źródło
źródło
Odpowiedzi:
Jest to termin używany w dynamicznych językach , które nie mają silnego pisania .
Chodzi o to, że nie potrzebujesz typu, aby wywołać istniejącą metodę na obiekcie - jeśli metoda jest na nim zdefiniowana, możesz ją wywołać.
Nazwa pochodzi od wyrażenia „Jeśli wygląda jak kaczka i kwacze jak kaczka, to jest kaczka”.
Wikipedia ma znacznie więcej informacji.
źródło
Wpisywanie kaczki oznacza, że operacja nie określa formalnie wymagań, które muszą spełnić jej operandy, a jedynie wypróbowuje to, co podano.
W przeciwieństwie do tego, co powiedzieli inni, niekoniecznie dotyczy to dynamicznych języków lub problemów z dziedziczeniem.
Przykładowe zadanie: Wywołaj metodę
Quack
na obiekcie.Bez użycia kaczego typu funkcja
f
wykonująca to zadanie musi z góry określić, że jej argument musi obsługiwać jakąś metodęQuack
. Powszechnym sposobem jest użycie interfejsówWywoływanie
f(42)
kończy się niepowodzeniem, alef(donald)
działa tak długo, jak długodonald
występuje instancjaIQuack
podtypu.Innym podejściem jest typowanie strukturalne - ale ponownie, metoda
Quack()
formalnie określa wszystko, co nie możequack
z góry udowodnić, że spowoduje awarię kompilatora.Moglibyśmy nawet pisać
w Haskell, gdzie
Quackable
krój pisma zapewnia istnienie naszej metody.Więc jak pisze kaczka zmienia to ?
Cóż, jak powiedziałem, system pisania kaczek nie określa wymagań, ale po prostu próbuje, jeśli coś działa .
Zatem dynamiczny system typów, taki jak Python, zawsze używa pisania kaczego:
Jeśli
f
otrzymax
wsparcieQuack()
, wszystko jest w porządku, jeśli nie, ulegnie awarii w czasie wykonywania.Ale pisanie kaczką wcale nie oznacza dynamicznego pisania - w rzeczywistości istnieje bardzo popularne, ale całkowicie statyczne pisanie kaczki, które również nie stwarza żadnych wymagań:
Ta funkcja nie mówi w żaden sposób, że chce takich,
x
które mogąQuack
, więc zamiast tego próbuje po prostu skompilować czas, a jeśli wszystko działa, jest w porządku.źródło
def f(x)
zamiastdef f(IQuack x)
.Proste objaśnienie (bez kodu)
Dyskusja na temat semantyki pytania jest dość szczegółowa (i bardzo akademicka), ale oto ogólna idea:
Pisanie kaczek
(„Jeśli chodzi jak kaczka i kwacze jak kaczka, to jest to kaczka.”) - TAK! ale co to znaczy?Najlepiej ilustruje to przykład:
Przykłady funkcji Kaczego Pisania:
Wyobraź sobie, że mam magiczną różdżkę. Ma specjalne uprawnienia. Jeśli macham różdżką i powiem „Jedź!”do samochodu, więc jeździ!
Czy działa na inne rzeczy? Nie jestem pewien: próbuję na ciężarówce. Wow - to też prowadzi! Następnie próbuję na samolotach, pociągach i 1 lesie (to rodzaj klubu golfowego, którego ludzie używają do „prowadzenia” piłki golfowej). Oni wszyscy jeżdżą!
Ale czy to zadziała powiedzmy, filiżanka do herbaty? Błąd: KAAAA-BOOOOOOM! to nie wyszło tak dobrze. ====> Filiżanki nie mogą prowadzić !! duh !?
Jest to w zasadzie koncepcja pisania kaczek. To system wypróbowania przed zakupem . Jeśli to działa, wszystko jest dobrze. Ale jeśli zawiedzie, jak granat wciąż w dłoni, wybuchnie ci w twarz.
Innymi słowy, jesteśmy zainteresowani tym, co obiekt może zrobić , a nie tym tym, czym jest obiekt .
Przykład: języki wpisywane statycznie
Jeśli martwimy się o to, czym właściwie jest obiekt , wówczas nasza magiczna sztuczka będzie działać tylko na wcześniej ustalonych, autoryzowanych typach - w tym przypadku samochodach, ale zawiedzie na innych obiektach, które mogą prowadzić : ciężarówkach, motorowerach, tuk-tuksach itp. Nie działa na ciężarówkach, ponieważ nasza magiczna różdżka oczekuje, że będzie działać tylko na samochodach .
Innymi słowy, w tym scenariuszu magiczna różdżka bardzo dokładnie przygląda się temu, czym jest obiekt (czy to samochód?), A nie tym, co może zrobić obiekt (np. Czy samochody, ciężarówki itp. Mogą jeździć).
Jedynym sposobem, aby zmusić ciężarówkę do jazdy, jest zdobycie magicznej różdżki, której można oczekiwać zarówno od ciężarówek, jak i samochodów (być może poprzez „wdrożenie wspólnego interfejsu”). Jeśli nie wiesz, co to znaczy, po prostu zignoruj to na chwilę.
Podsumowanie: Kluczowe wynos
W pisaniu kaczek ważne jest to, co obiekt może faktycznie zrobić, a nie to, czym jest obiekt .
źródło
Rozważ, że projektujesz prostą funkcję, która pobiera obiekt typu
Bird
i wywołuje jegowalk()
metodę. Istnieją dwa podejścia, o których możesz pomyśleć:Bird
, albo ich kod się nie skompiluje. Jeśli ktoś chce skorzystać z mojej funkcji, musi mieć świadomość, że akceptuję tylkoBird
sobjects
i po prostu wywołujęwalk()
metodę obiektu . Więc jeśliobject
puszkawalk()
jest poprawna, jeśli nie, moja funkcja zawiedzie. Więc tutaj nie jest ważne, że obiekt jestBird
cokolwiek innego, ważne jest, aby mógłwalk()
(To jest pisanie kaczki )Należy wziąć pod uwagę, że pisanie kaczką może być przydatne w niektórych przypadkach, na przykład Python często używa pisania kaczego .
Przydatne czytanie
źródło
Wikipedia ma dość szczegółowe wyjaśnienie:
http://en.wikipedia.org/wiki/Duck_typing
Ważna uwaga jest prawdopodobna, że podczas pisania kaczką deweloper bardziej interesuje się częściami obiektu, które są konsumowane, niż faktycznym typem bazowym.
źródło
Widzę wiele odpowiedzi, które powtarzają stary idiom:
a następnie zapoznaj się z wyjaśnieniem, co możesz zrobić z pisaniem kaczek, lub przykładem, który wydaje się zaciemniać tę koncepcję.
Nie znajduję zbyt wiele pomocy.
To najlepsza próba zwykłej angielskiej odpowiedzi na temat pisania kaczką, którą znalazłem:
Wpisywanie kaczki oznacza, że obiekt jest zdefiniowany przez to, co może zrobić, a nie przez to, czym jest.
Oznacza to, że jesteśmy mniej zainteresowani klasą / typem obiektu, a bardziej tym, jakie metody można na nim wywoływać i jakie operacje można na nim wykonywać. Nie dbamy o jego typ, dbamy o to, co może zrobić .
źródło
Pisanie kaczek:
Jest to zazwyczaj nazywa porwanie ( abductive rozumowanie lub zwany także retroduction , jaśniejszej definicji myślę):
z C (wniosek, co widzimy ) i R (zasada, co wiemy ), akceptujemy / decydujemy / zakładamy P (przesłanka, właściwość ), innymi słowy dany fakt
... podstawa diagnozy medycznej
z kaczkami: C = spacery, rozmowy , R = jak kaczka , P = to kaczka
Powrót do programowania:
obiekt o ma metodę / właściwość mp1, a interfejs / typ T wymaga / definiuje mp1
obiekt o ma metodę / właściwość mp2, a interfejs / typ T wymaga / definiuje mp2
...
Tak więc, więcej niż zwykłe zaakceptowanie mp1 ... dla dowolnego obiektu, o ile spełnia on jakąś definicję mp1 ..., kompilator / środowisko wykonawcze również powinno być w porządku z twierdzeniem o jest typu T
Cóż, czy tak jest w przypadku powyższych przykładów? Czy pisanie w Kaczce w ogóle nie polega na pisaniu? A może powinniśmy nazwać to niejawnym pisaniem?
źródło
Pomocne może być samo spojrzenie na język; często mi to pomaga (nie jestem rodzimym językiem angielskim).
W
duck typing
:1) słowo
typing
to nie oznacza pisania na klawiaturze (tak jak utrzymywał się w moim umyśle obraz), oznacza określenie „ jaki rodzaj rzeczy to ta rzecz? ”2) słowo
duck
wyraża, w jaki sposób dokonuje się tego ustalenia; to rodzaj „luźnego” określenia, jak w: „ jeśli chodzi jak kaczka ... to jest kaczka ”. Jest „luźny”, ponieważ rzecz może być kaczką lub nie, ale to, czy tak naprawdę jest kaczką, nie ma znaczenia; ważne jest to, że mogę to zrobić, co mogę zrobić z kaczkami i oczekiwać zachowań wykazywanych przez kaczki. Mogę nakarmić to bułką tartą i rzecz może pójść w moją stronę, rzucić się na mnie lub się wycofać ... ale nie pochłonie mnie tak, jak zrobiłby to grizzly.źródło
Wiem, że nie udzielam ogólnej odpowiedzi. W Ruby nie deklarujemy typów zmiennych ani metod - wszystko jest tylko rodzajem obiektu. Zatem reguła brzmi: „Klasy nie są typami”
W Ruby klasa nigdy nie jest (OK, prawie nigdy) typem. Zamiast tego typ obiektu jest bardziej określony przez to, co ten obiekt może zrobić. W Ruby nazywamy to pisaniem kaczek. Jeśli obiekt chodzi jak kaczka i mówi jak kaczka, tłumacz chętnie traktuje go jak kaczkę.
Na przykład możesz pisać procedurę dodawania informacji o utworze do ciągu. Jeśli pochodzisz z języka C # lub Java, możesz ulec pokusie napisania:
Wpisz kaczkę Ruby Ruby, a napiszesz coś o wiele prostszego:
Nie musisz sprawdzać typu argumentów. Jeśli obsługują << (w przypadku wyniku) lub tytuł i wykonawcę (w przypadku piosenki), wszystko po prostu zadziała. Jeśli nie, Twoja metoda i tak zgłosi wyjątek (tak jak zrobiłby to, gdybyś sprawdził typy). Ale bez sprawdzenia twoja metoda nagle staje się znacznie bardziej elastyczna. Możesz przekazać mu tablicę, ciąg, plik lub dowolny inny obiekt, który dołącza się za pomocą <<, i to po prostu zadziała.
źródło
Wpisywanie kaczek nie jest typem podpowiedzi!
Zasadniczo, aby użyć „pisania kaczego”, nie będziesz kierować na konkretny typ, ale raczej na szerszy zakres podtypów (nie mówiąc o dziedziczeniu, kiedy mam na myśli podtypy, mam na myśli „rzeczy” pasujące do tych samych profili) za pomocą wspólnego interfejsu .
Możesz sobie wyobrazić system, który przechowuje informacje. Aby pisać / czytać informacje, potrzebujesz pewnego rodzaju pamięci i informacji.
Rodzaje przechowywania mogą być następujące: plik, baza danych, sesja itp.
Interfejs poinformuje Cię o dostępnych opcjach (metodach) niezależnie od rodzaju pamięci, co oznacza, że w tym momencie nic nie jest zaimplementowane! Innymi słowy, interfejs nie wie nic o tym, jak przechowywać informacje.
Każdy system pamięci masowej musi wiedzieć o istnieniu interfejsu, wdrażając jego bardzo te same metody.
Teraz za każdym razem, gdy musisz pisać / czytać informacje:
W tym przykładzie używasz Duck Typing in Storage Konstruktor:
Mam nadzieję, że to pomogło;)
źródło
Przemierzanie drzewa techniką pisania kaczką
źródło
Myślę, że mieszanie pisania dynamicznego, pisania statycznego i pisania kaczego jest mylące. Pisanie kaczką jest niezależną koncepcją, a nawet statyczny język pisma, taki jak Go, może mieć system sprawdzania typów, który implementuje pisanie kaczych. Jeśli system typów sprawdzi metody (zadeklarowanego) obiektu, ale nie typ, można go nazwać językiem kaczym.
źródło
Staram się zrozumieć na swój sposób słynne zdanie: „Python nie obchodzi, czy przedmiot jest prawdziwą kaczką, czy nie. Wszystko zależy od tego, czy obiekt, pierwszy„ kwak ”, a drugi„ jak kaczka ”.
Jest dobra strona internetowa. http://www.voidspace.org.uk/python/articles/duck_typing.shtml#id14
Autor wskazał, że pisanie kaczych pozwala tworzyć własne klasy, które mają własną wewnętrzną strukturę danych - ale są dostępne przy użyciu normalnej składni Pythona.
źródło