@staticmethod vs funkcja na poziomie modułu

21

Tu nie chodzi o @staticmethodi @classmethod! Wiem jak staticmethoddziała. Chcę wiedzieć, jakie są właściwe przypadki użycia dla @staticmethodfunkcji na poziomie modułu.

Przejrzałem to pytanie i wydaje się, że istnieje ogólna zgoda co do tego, że funkcje na poziomie modułu są lepsze niż metody statyczne, ponieważ są bardziej pytoniczne. Zaletą metod statycznych jest bycie związanym z ich klasą, co może mieć sens, jeśli tylko ta klasa z nich korzysta. Jednak w Pythonie funkcjonalność jest zwykle uporządkowana według modułu, a nie klasy, więc zwykle czyniąc to funkcją modułu, również ma sens.

Metody statyczne można również zastąpić podklasami, co jest zaletą lub wadą w zależności od tego, jak na to patrzysz. Chociaż metody statyczne są zwykle „funkcjonalnie czyste”, więc przesłonięcie może nie być mądre, ale czasami może być wygodne (chociaż może to być jedna z tych „wygodnych, ale NIGDY NIE TO” rzeczy, których tylko doświadczenie może cię nauczyć).

Czy istnieją jakieś ogólne zasady dotyczące używania funkcji staticmethod lub funkcji na poziomie modułu? Jakie mają konkretne zalety lub wady (np. Przyszłe rozszerzenie, rozszerzenie zewnętrzne, czytelność)? Jeśli to możliwe, podaj także przykładowy przypadek.

Darkfeline
źródło

Odpowiedzi:

11

Technicznie metoda statyczna i funkcja modułu zachowują się prawie identycznie - w obu przypadkach działają one jak funkcje standardowe, a różnicą jest przestrzeń nazw, w której są umieszczone. Więc decyzja dotyczy bardziej łatwości konserwacji / czytelności.

Zasadniczo użyłbym metody statycznej, jeśli spełnione są niektóre lub wszystkie z tych kryteriów:

  • Istnieje już klasa z normalnymi metodami
  • Funkcja dotyczy ogólnie obiektów klasy, ale nie jednej konkretnej instancji
  • Chcesz móc wywoływać metodę tak, jakby była to metoda niestatyczna, być może dlatego, że możesz chcieć uczynić tę metodę niestatyczną w przyszłości bez łamania kodu klienta
Michael Slade
źródło
0

Program jest symulacją rzeczywistości. W ten sposób zależy to od tego, jak postrzegasz rzeczywistość.

Funkcja reprezentuje pewną aktywność. Im bardziej ogólna aktywność, tym większa jest tendencja do symulacji aktywności za pomocą funkcji. Metody są powiązane z klasami. Im bardziej aktywność jest specyficzna dla klasy, tym bardziej jest ona symulowana metodą.

Pomyśl o funkcjach trygonometrycznych. Powiedzmy, że sin()jest tak dobrze znany, że wiesz, że pasuje do siebie pod kątem. Wiesz, że chce liczby zmiennoprzecinkowej jako danych wejściowych i zwraca liczbę zmiennoprzecinkową. W każdym razie może istnieć typ danych kąta reprezentowany przez klasę, a .sin()argument bez może być normalną metodą, która działa z obiektem kąta, a .sin(x)jednym argumentem może być metoda statyczna klasy. Mogę się założyć, że coraz więcej osób uważa, że ​​lepiej jest zrobić sin()prostą funkcję. Są bardziej przyzwyczajeni.

Kolejny punkt widzenia : moduł przypomina instancję klasy. Ma własne zmienne składowe i funkcje składowe. W pewnym sensie implementuje wzorzec singletonu. Za każdym razem, gdy importujesz go z innego modułu aplikacji, masz dostęp do dokładnie tych samych zmiennych i funkcji.

pepr
źródło
0

Mam funkcję, która jako argument weźmie część głębokiej hierarchii danych obiektu. Zamiast tego przekazanie kilku argumentów potrzebnych do przejścia do tej części hierarchii danych byłoby kłopotliwe. Więc nie ma powodu, aby odwoływać się do siebie lub cls. Ale ta funkcjonalność będzie używana tylko na częściach obiektów określonej klasy. Wydaje mi się to metodą klasową.

Ponadto wolę importować nazwę klasy („z modułu klasy importu” niż „moduł modułu importu”). Włączenie funkcji jako metody statycznej daje mi dostęp do tej metody, a pisanie jej jako funkcji na poziomie modułu wymagałoby innego importu.

DVD Avins
źródło
2
Gdybym był tobą, unikałbym odpowiedzi w pierwszej osobie. To jest mylące. Zamiast tego powinieneś napisać do pytającego drugą osobę.
Aaron Hall,
Być może. Podałem przykładowy przypadek użycia, który może, ale nie musi odpowiadać temu, o co pytający miał na myśli.
Dvd Avins