Próbuję zrozumieć, co to jest łatanie małp czy łata małp?
Czy to coś w rodzaju przeciążenia metod / operatorów lub delegowania?
Czy ma coś wspólnego z tymi rzeczami?
python
terminology
monkeypatching
Siergiej Baszarow
źródło
źródło
Monkey patching is a technique to add, modify, or suppress the default behavior of a piece of code at runtime without changing its original source code.
Odpowiedzi:
Nie, to nie jest żadna z tych rzeczy. Jest to po prostu dynamiczna zamiana atrybutów w czasie wykonywania.
Rozważmy na przykład klasę, która ma metodę
get_data
. Ta metoda wykonuje zewnętrzne wyszukiwanie (na przykład w bazie danych lub interfejsie API sieci Web) i wywołują ją różne inne metody w klasie. Jednak w teście jednostkowym nie chcesz polegać na zewnętrznym źródle danych - więc dynamicznie zastępujeszget_data
metodę kodem zwrotnym, który zwraca niektóre ustalone dane.Ponieważ klasy Pythona są zmienne, a metody są tylko atrybutami klasy, możesz to zrobić tak, jak chcesz - a nawet zastąpić klasy i funkcje w module w dokładnie taki sam sposób.
Ale, jak zauważył komentator , należy zachować ostrożność podczas łączenia małp:
Jeśli oprócz testowych wywołań logicznych coś innego
get_data
, wywoła również zastąpione łatką małpy zamiast oryginalnego - co może być dobre lub złe. Tylko uważaj.Jeśli istnieje jakaś zmienna lub atrybut, który również wskazuje
get_data
funkcję do czasu jej zastąpienia, ten alias nie zmieni jej znaczenia i będzie nadal wskazywał na oryginałget_data
. (Dlaczego? Python po prostu ponownie wiąże nazwęget_data
w klasie z jakimś innym obiektem funkcji; nie ma to żadnego wpływu na inne wiązania nazw).źródło
pointing to the original get_data function
? Czy masz na myśli to, że gdy funkcja jest przechowywana w zmiennej, jeśli ktoś ją zmieni, zmienna będzie nadal wskazywać na poprzednią?get_data
, ponownie przypisujesz nazwęget_data
do fałszywej funkcji. Jeśli jakaś inna nazwa gdzieś w programie jest powiązana z funkcją-dawniej-znana-jako-get_data
, nic się nie zmieni dla tej innej nazwy.Prosty przykład wygląda następująco:
Źródło: strona MonkeyPatch na wiki Zope.
źródło
Mówiąc najprościej, łatanie małp wprowadza zmiany w module lub klasie podczas działania programu.
Przykład użycia
W dokumentacji Pand znajduje się przykład łatania małp:
Aby rozwiązać ten problem, najpierw importujemy nasz moduł:
Następnie tworzymy definicję metody, która istnieje niezwiązana i wolna poza zakresem jakichkolwiek definicji klas (ponieważ rozróżnienie między funkcją a niezwiązaną metodą jest dość pozbawione znaczenia, Python 3 eliminuje metodę niezwiązaną):
Następnie po prostu dołączamy tę metodę do klasy, na której chcemy jej użyć:
Następnie możemy użyć metody na instancji klasy i usunąć ją, gdy skończymy:
Zastrzeżenie dotyczące zmiany nazwy
Jeśli używasz manglingu nazw (przedrostek atrybutów z podwójnym podkreśleniem, który zmienia nazwę i którego nie polecam), będziesz musiał ręcznie nadać mu nazwę. Ponieważ nie polecam przekłamywania nazwisk, nie będę tego tutaj demonstrować.
Przykład testowy
Jak możemy wykorzystać tę wiedzę, na przykład podczas testowania?
Powiedzmy, że musimy zasymulować wywołanie pobierania danych do zewnętrznego źródła danych, które powoduje błąd, ponieważ w takim przypadku chcemy zapewnić prawidłowe zachowanie. Możemy małpować łatanie struktury danych, aby zapewnić takie zachowanie. (Więc używając podobnej nazwy metody, jak sugerował Daniel Roseman :)
A kiedy przetestujemy to pod kątem zachowania, które opiera się na tej metodzie powodującej błąd, jeśli zostanie poprawnie zaimplementowane, otrzymamy to zachowanie w wynikach testu.
Samo wykonanie powyższych czynności zmieni
Structure
obiekt na cały czas trwania procesu, więc będziesz chciał używać ustawień i rozbieżności w swoich najbardziej unikatowych miejscach, aby tego uniknąć, np .:(Chociaż powyższy jest w porządku, będzie to prawdopodobnie lepszy pomysł, aby korzystać z
mock
biblioteki załatać kod.mock
„Spatch
dekorator byłoby mniej podatne na błędy niż robi to powyżej, który musiałby otrzymać więcej linii kodu, a tym samym większe możliwości wprowadzenia błędów Muszę jeszcze przejrzeć kod,mock
ale wyobrażam sobie, że używa łatania małp w podobny sposób.)źródło
Według Wikipedii :
źródło
Po pierwsze: łatanie małp to zły hack (moim zdaniem).
Często służy do zastępowania metody na poziomie modułu lub klasy niestandardową implementacją.
Najczęstszym przypadkiem użycia jest dodanie obejścia błędu w module lub klasie, gdy nie można zastąpić oryginalnego kodu. W takim przypadku zamieniasz „zły” kod poprzez łatanie małp na implementację wewnątrz własnego modułu / pakietu.
źródło
Łatowanie małp można wykonywać tylko w dynamicznych językach, których dobrym przykładem jest Python. Przykładem jest zmiana metody w czasie wykonywania zamiast aktualizacji definicji obiektu; podobnie dodawanie atrybutów (metod lub zmiennych) w czasie wykonywania jest uważane za łatanie małp. Są to często wykonywane podczas pracy z modułami, dla których nie masz źródła, tak że definicji obiektów nie można łatwo zmienić.
Uznaje się to za złe, ponieważ oznacza, że definicja obiektu nie opisuje w pełni ani dokładnie, jak faktycznie się zachowuje.
źródło
Patchowanie małp powoduje ponowne otwarcie istniejących klas lub metod w środowisku uruchomieniowym i zmianę zachowania, które należy stosować ostrożnie, lub należy go używać tylko wtedy, gdy jest to naprawdę potrzebne.
Ponieważ Python jest dynamicznym językiem programowania, klasy można modyfikować, dzięki czemu można je ponownie otworzyć i zmodyfikować, a nawet zastąpić.
źródło
Aby uzyskać więcej informacji, zapoznaj się z [1]: https://medium.com/@nagillavenkatesh1234/monkey-patching-in-python-explained-with-examples-25eed0aea505
źródło