Koks skirtumas tarp „@staticmethod“ ir „@classmethod“?

Koks skirtumas tarp „ @staticmethod ir kitos „ @classmethod dekoruotos funkcijos?

2924
26 сент. nustatė Daryl Spitzer 26 sept. 2008-09-26 00:01 '08 ne 0:01 2008-09-26 00:01
@ 26 atsakymai

Galbūt mažas pavyzdžio kodas padės: atkreipkite dėmesį į skirtumą tarp foo , class_foo ir static_foo skambučių parašų:

 class A(object): def foo(self,x): print "executing foo(%s,%s)"%(self,x) @classmethod def class_foo(cls,x): print "executing class_foo(%s,%s)"%(cls,x) @staticmethod def static_foo(x): print "executing static_foo(%s)"%xa=A() 

Žemiau pateikiamas įprastas būdas, kaip objektas kviečia metodą. Objekto a egzempliorius a netiesiogiai perduodamas kaip pirmasis argumentas.

 a.foo(1) # executing foo(<__main__.A object at 0xb7dbef0c>,1) 

Naudojant klasės metodus, objekto egzempliorių klasė yra netiesiogiai perduodama kaip pirmasis argumentas vietoj self .

 a.class_foo(1) # executing class_foo(<class '__main__.A'>,1) 

Jūs taip pat galite skambinti class_foo naudodami klasę. Tiesą sakant, jei apibrėžiate kažką, ką reikia klasių metodui, tai tikriausiai yra todėl, kad ketinate jį pavadinti iš klasės, o ne iš klasės. A.foo(1) gali pavadinti „TypeError“, tačiau A.class_foo(1) veikia puikiai:

 a.class_foo(1) # executing class_foo(<class '__main__.A'>,1) 

Vienas iš žmonių naudojamų klasių metodų yra sukurti paveldėtus alternatyvius konstruktorius .


Naudojant statinius metodus, nei self (objekto pavyzdys), nei cls (klasė) netiesiogiai neperduodami kaip pirmasis argumentas. Jie elgiasi kaip paprastos funkcijos, išskyrus tai, kad galite juos skambinti iš pavyzdžio ar klasės:

 a.static_foo(1) # executing static_foo(1) A.static_foo('hi') # executing static_foo(hi) 

Statiniai metodai naudojami grupuoti funkcijas, turinčias logišką ryšį su klasės klase.


foo yra tik funkcija, bet kai skambinate „ a.foo , jūs ne tik gausite funkciją, bet ir „iš dalies pritaikytą“ funkcijos versiją su objekto „ a egzemplioriumi, kuris yra pirmasis funkcijos argumentas. foo tikisi 2 argumentų, o a.foo tikisi tik vieno argumento.

a privalomas. Štai ką reiškia „prijungtas“:

 print(a.foo) # <bound method A.foo of <__main__.A object at 0xb7d52f0c>> 

Su a.class_foo , a nėra susieta su class_foo , o klasė a susieta su class_foo .

 print(a.class_foo) # <bound method type.class_foo of <class '__main__.A'>> 

Čia, naudojant statinį metodą, nors tai yra metodas, a.static_foo tiesiog grąžina gerą ole funkciją be jokių privalomų argumentų. static_foo tikisi 1 argumento ir a.static_foo taip pat tikisi 1 argumento.

 print(a.static_foo) # <function static_foo at 0xb7d479cc> 

Ir, žinoma, tas pats atsitinka, kai skambinate static_foo su a klase.

 print(a.static_foo) # <function static_foo at 0xb7d479cc> 
2560
03 нояб. atsakymas pateiktas unutbu 03 lapkričio. 2009-11-03 22:13 '09 10:13 val. 2009-11-03 22:13

Statinis metodas yra metodas, kuris nieko nežino apie klasę ar pavyzdį, kuriam jis buvo pavadintas. Jis tiesiog gauna priimtus argumentus, tai nereiškia pirmojo argumento. Tai nenaudinga „Python“ - galite naudoti modulio funkciją vietoj statinio metodo.

Kita vertus, klasės metodas yra metodas, kuris gauna perduotą klasę, kuriai ji buvo paskirta, arba tos instancijos klasę, kuriai ji buvo paskirta, kaip pirmąjį argumentą. Tai naudinga, jei norite, kad šis metodas taptų klasės gamykla: kadangi jis gauna tikrąją klasę, kurią jis pavadino pirmuoju argumentu, visada galite sukurti teisingos klasės egzempliorių, net jei dalyvauja poklasiai. Atkreipkite dėmesį, pavyzdžiui, kaip dict.fromkeys() , klasės metodas grąžina poklasio egzempliorių, kai jis yra pakviestas poklasyje:

border=0
 >>> class DictSubclass(dict): ... def __repr__(self): ... return "DictSubclass" ... >>> dict.fromkeys("abc") {'a': None, 'c': None, 'b': None} >>> DictSubclass.fromkeys("abc") DictSubclass >>> 
708
26 сент. Thomas Wouters atsakymas 26 rugsėjis 2008-09-26 00:05 '08 0:05 2008-09-26 00:05

Iš esmės, @classmethod sukuria metodą, kurio pirmasis argumentas yra klasė, iš kurios jis vadinamas (o ne klasės egzempliorius) @staticmethod neturi implicitinių argumentų.

122
26 сент. atsakymą pateikė Terence Simpson 26 sept. 2008-09-26 00:07 '08 0:07 2008-09-26 00:07

Oficialūs „Python“ dokumentai:

@classmethod

Klasės metodas gauna klasę kaip numanomą pirmąjį argumentą, kaip ir metodo egzempliorius gauna egzempliorių. Jei norite deklaruoti klasės metodą, naudokite šį idiomą:

 class C: @classmethod def f(cls, arg1, arg2, ...): ... 

@classmethod forma yra dekoratoriaus funkcija - žr. Funkcijos apibrėžimo aprašymą apibrėžimo funkcijoje .

Jis gali būti vadinamas klasėje (pvz., Cf() ) arba egzemplioriuje (pvz., C().f() ). Pavyzdys ignoruojamas, išskyrus klasę. Jei klasės metodas vadinamas išvestine klase, išvestos klasės objektas yra pirmasis argumentas.

Klasės metodai skiriasi nuo C ++ arba Java statinių metodų. Jei norite, žr. Šiame skyriuje pateiktą staticmethod() .

@staticmethod

Statinis metodas nesuteikia netiesioginio argumento. Jei norite deklaruoti statinį metodą, naudokite šį idiomą:

 class C: @staticmethod def f(arg1, arg2, ...): ... 

@staticmethod forma yra dekoratoriaus funkcija - žr. Funkcijos apibrėžimo aprašymą apibrėžties funkcijoje .

Jis gali būti vadinamas klasėje (pvz., Cf() ) arba egzemplioriuje (pvz., C().f() ). Pavyzdys ignoruojamas, išskyrus klasę.

Statiniai Python metodai yra panašūs į tuos, kurie randami „Java“ arba „C ++“. Išsamesnės koncepcijos ieškokite šiame skyriuje pateiktame classmethod() .

82
03 нояб. Chris B. Atsakymas: 03 lapkritis. 2009-11-03 22:23 '09 at 10:23 AM 2009-11-03 22:23

Štai trumpas straipsnis šiuo klausimu.

„@Staticmethod“ funkcija yra tik klasėje apibrėžta funkcija. Jis gali būti panaudotas nesukuriant klasės egzemplioriaus. Jos apibrėžimas yra nepakeičiamas per paveldėjimą.

Funkcija „@classmethod“ taip pat gali būti vadinama nesukuriant klasės egzemplioriaus, tačiau jos apibrėžimas vyksta per Sub klasę, o ne tėvų klasę per paveldėjimą. Taip yra todėl, kad pirmasis argumentas, susijęs su @classmethod funkcija, visada turėtų būti cls (klasė).

62
03 нояб. Atsakymą pateikė Tom Neyland 03 lapkričio. 2009-11-03 22:02 '09 10:02 AM 2009-11-03 22:02

Jei norite nuspręsti, ar naudoti @staticmethod arba @classmethod, turite ieškoti savo metodo viduje. Jei jūsų metodas pasiekia kitus jūsų klasės kintamuosius / metodus, naudokite @classmethod . Kita vertus, jei jūsų metodas nėra susijęs su kitomis klasės dalimis, naudokite @staticmethod.

 class Apple: _counter = 0 @staticmethod def about_apple(): print('Apple is good for you.') # note you can still access other member of the class # but you have to use the class instance # which is not very nice, because you have repeat yourself # # For example: # @staticmethod # print('Number of apples have been juiced: %s' % Apple._counter) # # @classmethod # print('Number of apples have been juiced: %s' % cls._counter) # # @classmethod is especially useful when you move your function to other class, # you don't have to rename the class reference @classmethod def make_apple_juice(cls, number_of_apples): print('Make juice:') for i in range(number_of_apples): cls._juice_this(i) @classmethod def _juice_this(cls, apple): print('Juicing %d...' % apple) cls._counter += 1 
52
22 апр. atsakymą pateikė Du D. Balandžio 22 d 2016-04-22 18:40 '16 at 18:40 pm 2016-04-22 18:40

Koks skirtumas tarp @staticmethod ir @classmethod Python?

Galbūt matėte „Python“ kodą, pvz., Šį pseudokodą, kuris rodo įvairių tipų metodų parašus ir suteikia galimybę paaiškinti kiekvieną iš jų:

 class Foo(object): def a_normal_instance_method(self, arg_1, kwarg_2=None): ''' Return a value that is a function of the instance with its attributes, and other arguments such as arg_1 and kwarg2 ''' @staticmethod def a_static_method(arg_0): ''' Return a value that is a function of arg_0. It does not know the instance or class it is called from. ''' @classmethod def a_class_method(cls, arg1): ''' Return a value that is a function of the class and other arguments. respects subclassing, it is called with the class it is called from. ''' 

Įprastas pavyzdžio metodas

Pirmiausia paaiškinsiu „ a_normal_instance_method . Tai tiksliai vadinama instancijos metodu . Kai naudojamas egzempliorinis metodas, jis naudojamas kaip dalinė funkcija (priešingai nei visoms funkcijoms, apibrėžtoms visoms reikšmėms, kai žiūrima iš pradinio kodo), kuri, panaudojus pirmąjį argumentą, yra iš anksto apibrėžta kaip egzemplioriaus objektas su visais jo atributais. Jis turi su juo susieto objekto egzempliorių ir turi būti iškviestas iš objekto instancijos. Paprastai jis bus susijęs su įvairiais instancijos atributais.

Pavyzdžiui, tai yra eilutės pavyzdys:

 ', ' 

jei naudojame pavyzdžio metodą join prie šios linijos, kad prisijungtume prie kito iterable, tai akivaizdu, kad egzemplioriaus funkcija, be iteruoto sąrašo funkcijos, yra ['a', 'b', 'c'] :

 >>> ', '.join(['a', 'b', 'c']) 'a, b, c' 

Susiję metodai

Pavyzdžių metodus galima susieti per taškinę paiešką, kad galėtumėte juos naudoti vėliau.

Pavyzdžiui, jis susieja metodą str.join su ':' pavyzdžiu:

 >>> join_with_colons = ':'.join 

Ir vėliau mes galime tai naudoti kaip funkciją, kuri jau turi pirmąjį su juo susijusį argumentą. Taigi jis veikia kaip dalinė instancijos funkcija:

 >>> join_with_colons('abcde') 'a:b:c:d:e' >>> join_with_colons(['FF', 'FF', 'FF', 'FF', 'FF', 'FF']) 'FF:FF:FF:FF:FF:FF' 

Statinis metodas

Statinis metodas nepriima egzemplioriaus kaip argumento.

Jis labai panašus į modulio lygio funkciją.

Tačiau modulio lygio funkcija turi gyventi modulyje ir būti specialiai importuojama į kitas vietas, kuriose ji naudojama.

Jei jis yra prijungtas prie objekto, taip pat patogu pereiti per objektą per importą ir paveldėjimą.

Statinio metodo pavyzdys yra str.maketrans , perkeltas iš string modulio į Python 3. Tai leidžia vertimo lentelę pritaikyti vartojimui str.translate . Tai atrodo gana kvaila, kai naudojama iš eilutės, kaip parodyta žemiau, tačiau funkcijos importavimas iš string modulio yra gana nepatogu, ir malonu, kad galėtumėte jį pavadinti iš klasės, kaip ir str.maketrans

 # demonstrate same function whether called from instance or not: >>> ', '.maketrans('ABC', 'abc') {65: 97, 66: 98, 67: 99} >>> str.maketrans('ABC', 'abc') {65: 97, 66: 98, 67: 99} 

„Python 2“ programoje šią funkciją reikia importuoti iš vis mažiau naudingos eilutės modulio:

 >>> import string >>> 'ABCDEFG'.translate(string.maketrans('ABC', 'abc')) 'abcDEFG' 

Klasės metodas

Klasės metodas yra panašus į egzemplioriaus metodą, nes jis priima netiesioginį pirmąjį argumentą, bet vietoj to, kad priima pavyzdį, jis priima klasę. Dažnai jie naudojami kaip alternatyvūs konstruktoriai geresniam semantiniam naudojimui, ir jie rems paveldėjimą.

Labiausiai kanoninis įmontuotos klasės pavyzdys yra dict.fromkeys . Jis naudojamas kaip alternatyvus dikto konstruktorius (gerai tinka, kai žinote, ką turite, ir norite, kad jie būtų numatytieji.)

 >>> dict.fromkeys(['a', 'b', 'c']) {'c': None, 'b': None, 'a': None} 

Kai mes subklasuojame diktą, galime naudoti tą patį konstruktorių, kuris sukuria poklasio egzempliorių.

 >>> class MyDict(dict): 'A dict subclass, use to demo classmethods' >>> md = MyDict.fromkeys(['a', 'b', 'c']) >>> md {'a': None, 'c': None, 'b': None} >>> type(md) <class '__main__.MyDict'> 

Kitų panašių alternatyvių konstruktorių pavyzdžių, taip pat oficialų „Python“ dokumentą apie klasės classmethod ir staticmethod .

40
23 янв. Atsakymą pateikė Aaron Hall sausio 23 d. 2015-01-23 23:01 '15, 11:01 pm 2015-01-23 23:01

@ dekoratoriai buvo įtraukti į python 2.4 Jei naudojate python <2.4, galite naudoti klasių metodų () ir statinio metodo () funkcijas.

Pvz., Jei norite sukurti gamyklinį metodą (funkciją, kuri grąžina kitos klasės diegimą, priklausomai nuo to, kokį argumentą ji priima), galite padaryti kažką panašaus:

 class Cluster(object): def _is_cluster_for(cls, name): """ see if this class is the cluster with this name this is a classmethod """ return cls.__name__ == name _is_cluster_for = classmethod(_is_cluster_for) #static method def getCluster(name): """ static factory method, should be in Cluster class returns a cluster object for the given name """ for cls in Cluster.__subclasses__(): if cls._is_cluster_for(name): return cls() getCluster = staticmethod(getCluster) 

Taip pat atkreipkite dėmesį, kad tai yra geras pavyzdys, kaip naudoti klasės metodą ir statinį metodą, statinis metodas aiškiai priklauso klasei, nes jis naudoja vidinį klasės klasterį. Klasei reikia tik informacijos apie klasę, o ne objekto pavyzdį.

Dar vienas „ _is_cluster_for klasės metodo sukūrimo privalumas yra tas, kad poklasis gali nuspręsti keisti jo įgyvendinimą, galbūt todėl, kad jis yra gana dažnas ir gali tvarkyti kelis klasterių tipus, todėl tiesiog nepakanka klasės pavadinimo tikrinimo.

28
24 февр. Jens Timmerman atsakymas, pateiktas vasario 24 d. 2012-02-24 12:32 '12 12:32 2012-02-24 12:32

Manau, geriausias klausimas yra toks: „Kada jūs naudosite @classmethod vs @staticmethod?“

@classmethod leidžia jums lengvai pasiekti privačius narius, susijusius su klasės apibrėžimu. Tai puikus būdas sukurti vienišas ar gamyklines klases, kurios kontroliuoja sukurtų objektų skaičių.

@staticmethod suteikia ribinius našumo padidėjimus, bet vis dar turiu pamatyti produktyvų statinio metodo naudojimą klasėje, kuri negali būti vykdoma kaip autonominė funkcija už klasės ribų.

27
19 мая '15 в 18:27 2015-05-19 18:27 Atsakymą pateikė Nathan Tregillus gegužės 19, 15, 18:27 2015-05-19 18:27

Statiniai metodai:

  • Paprasta funkcija be argumentų.
  • Darbas su klasės atributais; ne pavyzdžių atributai.
  • Galite skambinti per klasę ir egzempliorių.
  • Norint juos sukurti, naudojama integruota statinio metodo () funkcija.

Statinių metodų privalumai:

  • Jis lokalizuoja funkcijos pavadinimą į klasę.
  • Jis perkelia funkcijų kodą arčiau to, kur jis naudojamas.
  • Funkcijų importavimas modulio lygmeniu yra patogesnis, nes nereikia konkrečiai importuoti kiekvieno metodo

     @staticmethod def some_static_method(*args, **kwds): pass 

Klasės metodai:

  • Funkcijos, turinčios pirmąjį argumentą kaip klasės pavadinimas.
  • Galite skambinti per klasę ir egzempliorių.
  • Jie sukuriami naudojant įmontuotą klasių metodą.

      @classmethod def some_class_method(cls, *args, **kwds): pass 
26
03 окт. Atsakyti Laxmi Oct 03. 2016-10-03 13:41 '16 at 13:41 pm 2016-10-03 13:41

@staticmethod tiesiog išjungia numatytąją funkciją kaip metodo rankeną. Klasės metodas apgaubia jūsų funkciją į konteinerį, kuris vadina nuorodą į savo klasę kaip pirmąjį argumentą:

 >>> class C(object): ... pass ... >>> def f(): ... pass ... >>> staticmethod(f).__get__(None, C) <function f at 0x5c1cf0> >>> classmethod(f).__get__(None, C) <bound method type.f of <class '__main__.C'>> 

Tiesą sakant, klasės classmethod turi aptarnavimo duomenis vykdymo metu, tačiau leidžia prieiti prie savininko klasės. Arba rekomenduoju naudoti metaklasę ir priskirti klasės metodus šioje metaklasėje:

 >>> class CMeta(type): ... def foo(cls): ... print cls ... >>> class C(object): ... __metaclass__ = CMeta ... >>> C.foo() <class '__main__.C'> 
21
26 сент. atsakymą pateikė Armin Ronacher 26 sep . 2008-09-26 00:24 '08 ne 0:24 2008-09-26 00:24

Galutinis vadovas, kaip naudoti „Python“ statinius, vėsius ar abstrakčius metodus, yra vienas iš gerų šios temos nuorodų ir sumažina juos iki šių.

@staticmethod funkcija yra tik klasėje apibrėžta funkcija. Jis gali būti panaudotas nesukuriant klasės egzemplioriaus. Jos apibrėžimas yra nepakeičiamas per paveldėjimą.

  • „Python“ neturėtų išreikšti susieto objekto metodo.
  • Tai palengvina kodo įskaitomumą ir nepriklauso nuo paties objekto būklės;

Funkcija „ @classmethod pat @classmethod būti @classmethod be klasės, tačiau jos apibrėžimas atitinka sub poklasį, o ne pirminės klasės, per paveldėjimą, gali būti iš naujo apibrėžtas poklasyje. Taip yra todėl, kad pirmasis argumentas, susijęs su @classmethod funkcija, visada @classmethod būti cls (klasė).

  • Gamykliniai metodai, naudojami kuriant klasę, kuri naudoja, pavyzdžiui, tam tikrą išankstinį apdorojimą.
  • Statiniai metodai, vadinantys statinius metodus: jei sulaužote statinius metodus keliais statiniais metodais, neturėtumėte griežtai koduoti klasės pavadinimo, bet naudoti klasės metodus
18
16 нояб. Atsakymas pateikiamas zangw 16 lapkričio. 2015-11-16 05:00 '15 5:00 val. 2015-11-16 05:00

Pradėjau mokytis programavimo kalbos su C + +, o tada su „Java“ ir tada su „Python“, todėl šis klausimas man taip pat trukdė, kol supratau paprastą kiekvieno iš jų naudojimą.

Klasės metodas: „ Python“, skirtingai nei „Java“ ir „C ++“, neturi konstruktoriaus perkrovos. Todėl, norėdami tai pasiekti, galite naudoti klasės classmethod . Toliau pateiktas pavyzdys tai paaiškins.

Tarkime, kad mes turime Person klasę, kurioje yra du argumentai, first_name ir paskutinis vardas last_name ir sukuriamas Asmens egzempliorius.

 class Person(object): def __init__(self, first_name, last_name): self.first_name = first_name self.last_name = last_name 

Dabar, jei atsiranda reikalavimas, kur jums reikia sukurti klasę, naudojant tik vieną pavadinimą, tiesiog first_name vardas, negalite kažką panašaus padaryti first_name .

Tai suteiks jums klaidą bandant sukurti objektą (pavyzdį).

 class Person(object): def __init__(self, first_name, last_name): self.first_name = first_name self.last_name = last_name def __init__(self, first_name): self.first_name = first_name 

Tačiau tą patį galite pasiekti naudodami @classmethod .

 class Person(object): def __init__(self, first_name, last_name): self.first_name = first_name self.last_name = last_name @classmethod def get_person(cls, first_name): return cls(first_name, "") 

Statinis metodas :: Tai gana paprasta, ji nėra susieta su egzemplioriumi ar klase, ir jūs galite tiesiog jį pavadinti naudodami klasės pavadinimą.

Taigi, pavyzdžiui, aukščiau pateiktame pavyzdyje turite patikrinti, ar first_name neturėtų viršyti 20 simbolių, galite tai padaryti.

 @staticmethod def validate_name(name): return len(name) <= 20 

ir galite tiesiog skambinti naudodami klasės pavadinimą

 Person.validate_name("Gaurang Shah") 
17
10 окт. Atsakyti Gaurang Shah Oct 10 2017-10-10 13:10 '17, 13.10 val. 2017-10-10 13:10

@classmethod reiškia : skambindami šiuo metodu, mes perduodame klasę kaip pirmąjį argumentą vietoj šios klasės egzemplioriaus (kaip mes paprastai darome su metodais). Tai reiškia, kad jūs galite naudoti klasę ir jos savybes šiame metode, o ne konkrečiu atveju.

„@staticmethod“ reiškia: kai šis metodas vadinamas, mes nesuteikiame jam klasės egzemplioriaus (kaip tai paprastai būna taikant metodus). Tai reiškia, kad galite priskirti funkciją klasės viduje, bet negalite pasiekti šios klasės egzemplioriaus (tai naudinga, kai jūsų metodas nenaudoja instancijos).

16
13 дек. Atsakymą pateikė Tushar.PUCSD gruodžio 13 d. 2015-12-13 22:37 '15, 10:37 pm 2015-12-13 22:37

Kitas aspektas, susijęs su statinio metodo ir klasės metodo taikymu, yra susijęs su paveldėjimu. Tarkime, jūs turite šią klasę:

 class Foo(object): @staticmethod def bar(): return "In Foo" 

Ir tada norite perrašyti vaikiškos klasės bar() :

 class Foo2(Foo): @staticmethod def bar(): return "In Foo2" 

Tai veikia, bet atkreipkite dėmesį, kad dabar bar() įgyvendinimas vaikų klasėje ( Foo2 ) nebegali naudoti nieko, kas būdingas šiai klasei. Pavyzdžiui, tarkime, kad „ Foo2 turėjo magic() metodą, kurį norite naudoti įgyvendinant „ Foo2 bar() :

 class Foo2(Foo): @staticmethod def bar(): return "In Foo2" @staticmethod def magic(): return "Something useful you'd like to use in bar, but now can't" 

Foo2.magic() čia būtų paskambinti „ Foo2.magic() bar() , bet tada kartoti (jei pasikeičia „ Foo2 pavadinimas, turėsite prisiminti šį metodų bar() ).

Man tai yra nedidelis atviro / uždarojo principo pažeidimas , nes sprendimas, priimtas Foo daro įtaką jūsų refaktoriaus bendram kodo gebėjimui išvestoje klasėje (t. Y. Jis yra mažiau atviras plėtrai). Jei bar() buvo klasės classmethod , mes būtume gerai:

 class Foo(object): @classmethod def bar(cls): return "In Foo" class Foo2(Foo): @classmethod def bar(cls): return "In Foo2 " + cls.magic() @classmethod def magic(cls): return "MAGIC" print Foo2().bar() 

Suteikia: In Foo2 MAGIC

10
29 сент. Atsakymą pateikė Adam Parkin 29 sep. 2016-09-29 20:02 '16 at 20:02 2016-09-29 20:02

Pirmiausia norėčiau pakalbėti apie metodo panašumą, dekoruotą @ classmethod vs @staticmethod.

Panašumai: abu jie gali būti vadinami pačia klase, o ne tik klasės klasėje. Taigi, abu jie tam tikra prasme yra klasės metodai.

Skirtumas: klasės metodas bus pirmasis argumentas, tačiau statinis metodas nebus.

Taigi, statinis metodas tam tikra prasme nėra susijęs su pačia klase ir tiesiog pakimba ten tik todėl, kad jis gali turėti panašių funkcijų.

 >>> class Klaus: @classmethod def classmthd(*args): return args @staticmethod def staticmthd(*args): return args # 1. Call classmethod without any arg >>> Klaus.classmthd() (__main__.Klaus,) # the class gets passed as the first argument # 2. Call classmethod with 1 arg >>> Klaus.classmthd('chumma') (__main__.Klaus, 'chumma') # 3. Call staticmethod without any arg >>> Klaus.staticmthd() () # 4. Call staticmethod with 1 arg >>> Klaus.staticmthd('chumma') ('chumma',) 
10
14 янв. Atsakymą Selva pateikė sausio 14 d. 2018-01-14 17:07 '18, 17:07 val. 2018-01-14 17:07

Bandysiu paaiškinti pagrindinį skirtumą su pavyzdžiu.

 class A(object): x = 0 def say_hi(self): pass @staticmethod def say_hi_static(): pass @classmethod def say_hi_class(cls): pass def run_self(self): self.x += 1 print self.x # outputs 1 self.say_hi() self.say_hi_static() self.say_hi_class() @staticmethod def run_static(): print Ax # outputs 0 # A.say_hi() # wrong A.say_hi_static() A.say_hi_class() @classmethod def run_class(cls): print cls.x # outputs 0 # cls.say_hi() # wrong cls.say_hi_static() cls.say_hi_class()