Czy możliwe jest posiadanie statycznych metod w Pythonie, które mógłbym wywołać bez inicjowania klasy, takich jak:
ClassName.static_method()
źródło
Czy możliwe jest posiadanie statycznych metod w Pythonie, które mógłbym wywołać bez inicjowania klasy, takich jak:
ClassName.static_method()
Tak, używając dekoratora staticmethod
class MyClass(object):
@staticmethod
def the_static_method(x):
print(x)
MyClass.the_static_method(2) # outputs 2
Zauważ, że w niektórych kodach może być używana stara metoda definiowania metody statycznej, używana staticmethod
raczej jako funkcja niż dekorator. Należy tego używać tylko wtedy, gdy musisz obsługiwać starsze wersje Pythona (2.2 i 2.3)
class MyClass(object):
def the_static_method(x):
print(x)
the_static_method = staticmethod(the_static_method)
MyClass.the_static_method(2) # outputs 2
Jest to całkowicie identyczne z pierwszym przykładem (używanie @staticmethod
), po prostu nie używanie ładnej składni dekoratora
Wreszcie, używaj staticmethod()
oszczędnie! Istnieje bardzo niewiele sytuacji, w których w Pythonie potrzebne są metody statyczne i widziałem, że były one używane wiele razy, w których oddzielna funkcja „najwyższego poziomu” byłaby jaśniejsza.
Z dokumentacji wynika dosłownie :
Metoda statyczna nie otrzymuje domyślnego pierwszego argumentu. Aby zadeklarować metodę statyczną, użyj tego idiomu:
class C: @staticmethod def f(arg1, arg2, ...): ...
Forma @staticmethod jest dekoratorem funkcji - szczegółowe informacje można znaleźć w opisie definicji funkcji w Definicjach funkcji .
Można go wywołać w klasie (np.
C.f()
) Lub w instancji (np.C().f()
). Instancja jest ignorowana z wyjątkiem swojej klasy.Metody statyczne w Pythonie są podobne do metod znalezionych w Javie lub C ++. Bardziej zaawansowaną koncepcję, patrz
classmethod()
.Aby uzyskać więcej informacji na temat metod statycznych, zapoznaj się z dokumentacją dotyczącą standardowej hierarchii typów w sekcji Standardowa hierarchia typów .
Nowości w wersji 2.2.
Zmieniono w wersji 2.4: Dodano składnię dekoratora funkcji.
@staticmethod
dekoracje lub używać wskaźnika funkcji, skoro można po prostu uniknąć pierwszegoself
parametru? Cóż, dla obiektua
nie będziesz mógł wywoływaća.your_static_method()
, co jest dozwolone w innych językach, ale i tak jest to uważane za złą praktykę, a kompilator zawsze ostrzega przed tymClassName.methodName()
, jakby była statyczna, a następnie nieself
zostanie przekazana żadna metoda. Jak powiedziałeś, nadal będzie można wywołać tę metodę jakoClassInstance.methodName()
iself
będzie ona podawana jako pierwszy parametr, niezależnie od jego nazwy.Myślę, że Steven ma rację . Aby odpowiedzieć na pierwotne pytanie, w celu ustawienia metody klasy po prostu załóż, że pierwszy argument nie będzie instancją wywołującą, a następnie upewnij się, że metoda wywoływana jest tylko z klasy.
(Zauważ, że ta odpowiedź odnosi się do Pythona 3.x. W Pythonie 2.x otrzymasz
TypeError
wywołanie metody na samej klasie).Na przykład:
W tym kodzie metoda „rollCall” zakłada, że pierwszy argument nie jest instancją (tak jakby był wywołany przez instancję zamiast klasy). Dopóki „rollCall” jest wywoływany z klasy, a nie z instancji, kod będzie działał poprawnie. Jeśli spróbujemy wywołać „rollCall” z instancji, np .:
spowodowałoby to jednak wyjątek, ponieważ wysłałby dwa argumenty: siebie i -1, a „rollCall” jest zdefiniowany tak, aby akceptował tylko jeden argument.
Nawiasem mówiąc, rex.rollCall () wyśle poprawną liczbę argumentów, ale spowoduje także zgłoszenie wyjątku, ponieważ teraz n będzie reprezentował instancję Dog (tj. Rex), gdy funkcja spodziewa się, że n będzie liczbą.
W tym momencie pojawia się dekoracja: jeśli poprzedzimy metodę „rollCall”
następnie, stwierdzając wprost, że metoda jest statyczna, możemy nawet wywołać ją z instancji. Teraz,
pracowałbym. Wstawienie @staticmethod przed definicją metody powstrzymuje instancję przed wysłaniem się jako argumentu.
Możesz to sprawdzić, wypróbowując poniższy kod z komentarzem i bez linii @staticmethod.
źródło
TypeError: unbound method rollCall() must be called with Dog instance as first argument (got int instance instead)
T.my_static_method()
lubtype(my_t_instance).my_static_method()
, ponieważ jest to jaśniejsze i od razu widać, że wywołuję metodę statyczną.Tak, sprawdź dekorator staticmethod :
źródło
Naprawdę nie musisz używać
@staticmethod
dekoratora. Wystarczy zadeklarować metodę (która nie oczekuje parametru własnego) i wywołać ją z klasy. Dekorator jest tylko w przypadku, gdy chcesz mieć możliwość wywołania go również z instancji (czego nie chciałeś zrobić)Najczęściej używasz tylko funkcji ...
źródło
class Dummy: def static1(): print "hello from static1" @staticmethod def static2(): print "hello from static2" Dummy.static2() Dummy.static1()
Wyjście: hello from static2 Traceback <ostatnie ostatnie wywołanie>: Plik „ll.py”, wiersz 46, w <module> Dummy.static1 () TypeError: metoda niezwiązana static1 () musi być wywołany z instancją Dummy jako pierwszy argument (zamiast tego nic nie dostał)self
jako pierwszy argument, chyba że powiesz mu, żeby tego nie robił. (patrz: dekorator)self
ref w zależności od tego, jak się nazywa. Przypadek testowy: pastebin.com/12DDV7DB .staticmethod
Dekorator pozwala wywołać funkcję zarówno w klasie i instancji (rozwiązanie to nie powiedzie się podczas wywoływania funkcji w instancji).class C: def callme(): print('called'); C.callme()
Tak, metody statyczne można tworzyć w ten sposób (chociaż nieco bardziej Pythonic używa do podkreślania metod zamiast CamelCase):
Powyżej używa składni dekoratora. Ta składnia jest równoważna z
Można tego użyć zgodnie z opisem:
Wbudowany przykład metody statycznej znajduje się
str.maketrans()
w Pythonie 3, który był funkcją wstring
module w Pythonie 2.Inną opcją, której można użyć podczas opisywania, jest to
classmethod
, że różnica polega na tym, że metoda class pobiera klasę jako domyślny pierwszy argument, a jeśli jest podklasą, otrzymuje podklasę jako domyślny pierwszy argument.Zauważ, że
cls
nie jest to wymagana nazwa pierwszego argumentu, ale większość doświadczonych programistów Pythona uzna to za źle zrobione, jeśli użyjesz czegoś innego.Są one zwykle używane jako alternatywne konstruktory.
Wbudowanym przykładem jest
dict.fromkeys()
:źródło
Poza szczególnymi cechami zachowania się obiektów metod statycznych , istnieje pewien rodzaj piękna, z którym możesz się nimi zaatakować, jeśli chodzi o organizację kodu na poziomie modułu.
...
...
...
Staje się teraz nieco bardziej intuicyjny i samok dokumentujący się w kontekście, w którym mają być używane określone komponenty, i idealnie nadaje się do nazwania odrębnych przypadków testowych, a także ma proste podejście do sposobu mapowania modułów testowych na moduły testowane dla purystów .
Często uważam, że zastosowanie tego podejścia do organizacji kodu narzędziowego projektu jest opłacalne. Dość często ludzie natychmiast spieszą się i tworzą
utils
pakiet i kończą z 9 modułami, z których jeden ma 120 LOC, a reszta to w najlepszym razie dwa tuziny LOC. Wolę zacząć od tego i przekształcić go w pakiet i tworzyć moduły tylko dla bestii, które naprawdę na nie zasługują:źródło
Być może najprostszą opcją jest po prostu umieszczenie tych funkcji poza klasą:
Za pomocą tej metody funkcje, które modyfikują lub wykorzystują wewnętrzny stan obiektu (wywołują skutki uboczne) mogą być przechowywane w klasie, a funkcje narzędziowe wielokrotnego użytku można przenieść na zewnątrz.
Powiedzmy, że ten plik się nazywa
dogs.py
. Aby ich użyć, zadzwońdogs.barking_sound()
zamiastdogs.Dog.barking_sound
.Jeśli naprawdę potrzebujesz metody statycznej, aby być częścią klasy, możesz użyć dekoratora staticmethod .
źródło
Tak więc metody statyczne to metody, które można wywoływać bez tworzenia obiektu klasy. Na przykład :-
W powyższym przykładzie metoda
add
jest wywoływana przez nazwę klasy, aA
nie nazwę obiektu.źródło
Metody statyczne w języku Python można tworzyć na dwa sposoby.
Używanie staticmethod ()
Wynik:
Wynik: 25
Korzystanie z @staticmethod
Wynik:
Wynik: 25
źródło
Od czasu do czasu napotykam to pytanie. Przypadek użycia i przykład, który lubię to:
Nie ma sensu tworzyć obiektów klasy cmath, ponieważ nie ma stanu w obiekcie cmath. Jednak cmath to zbiór metod, które są w jakiś sposób powiązane. W powyższym przykładzie wszystkie funkcje cmath działają w pewien sposób na liczbach zespolonych.
źródło