Python's Instance, Class, and Static Methods Demystified

文章推薦指數: 80 %
投票人數:10人

Key Takeaways · Instance methods need a class instance and can access the instance through self . · Class methods don't need a class instance. · Static methods don ... Start Here LearnPython PythonTutorials→In-deptharticlesandvideocourses LearningPaths→Guidedstudyplansforacceleratedlearning Quizzes→Checkyourlearningprogress BrowseTopics→Focusonaspecificareaorskilllevel CommunityChat→LearnwithotherPythonistas OfficeHours→LiveQ&AcallswithPythonexperts Podcast→Hearwhat’snewintheworldofPython Books→Roundoutyourknowledgeandlearnoffline UnlockAllContent→ More PythonLearningResources PythonNewsletter PythonJobBoard MeettheTeam BecomeaTutorialAuthor BecomeaVideoInstructor Search Join Sign‑In Python'sInstance,Class,andStaticMethodsDemystified byDanBader intermediate python MarkasCompleted Tweet Share Email TableofContents Instance,Class,andStaticMethods—AnOverview InstanceMethods ClassMethods StaticMethods Let’sSeeThemInAction! DeliciousPizzaFactoriesWith@classmethod WhenToUseStaticMethods KeyTakeaways Removeads WatchNowThistutorialhasarelatedvideocoursecreatedbytheRealPythonteam.Watchittogetherwiththewrittentutorialtodeepenyourunderstanding:OOPMethodTypesinPython:@classmethodvs@staticmethodvsInstanceMethods InthistutorialI’llhelpdemystifywhat’sbehindclassmethods,staticmethods,andregularinstancemethods. Ifyoudevelopanintuitiveunderstandingfortheirdifferencesyou’llbeabletowriteobject-orientedPythonthatcommunicatesitsintentmoreclearlyandwillbeeasiertomaintaininthelongrun. FreeBonus:ClickheretogetaccesstoafreePythonOOPCheatSheetthatpointsyoutothebesttutorials,videos,andbookstolearnmoreaboutObject-OrientedProgrammingwithPython. Instance,Class,andStaticMethods—AnOverview Let’sbeginbywritinga(Python3)classthatcontainssimpleexamplesforallthreemethodtypes: classMyClass: defmethod(self): return'instancemethodcalled',self @classmethod defclassmethod(cls): return'classmethodcalled',cls @staticmethod defstaticmethod(): return'staticmethodcalled' NOTE:ForPython2users:The@staticmethodand@classmethoddecoratorsareavailableasofPython2.4andthisexamplewillworkasis.InsteadofusingaplainclassMyClass:declarationyoumightchoosetodeclareanew-styleclassinheritingfromobjectwiththeclassMyClass(object):syntax.Otherthanthatyou’regoodtogo. RemoveadsInstanceMethods ThefirstmethodonMyClass,calledmethod,isaregularinstancemethod.That’sthebasic,no-frillsmethodtypeyou’llusemostofthetime.Youcanseethemethodtakesoneparameter,self,whichpointstoaninstanceofMyClasswhenthemethodiscalled(butofcourseinstancemethodscanacceptmorethanjustoneparameter). Throughtheselfparameter,instancemethodscanfreelyaccessattributesandothermethodsonthesameobject.Thisgivesthemalotofpowerwhenitcomestomodifyinganobject’sstate. Notonlycantheymodifyobjectstate,instancemethodscanalsoaccesstheclassitselfthroughtheself.__class__attribute.Thismeansinstancemethodscanalsomodifyclassstate. ClassMethods Let’scomparethattothesecondmethod,MyClass.classmethod.Imarkedthismethodwitha@classmethoddecoratortoflagitasaclassmethod. Insteadofacceptingaselfparameter,classmethodstakeaclsparameterthatpointstotheclass—andnottheobjectinstance—whenthemethodiscalled. Becausetheclassmethodonlyhasaccesstothisclsargument,itcan’tmodifyobjectinstancestate.Thatwouldrequireaccesstoself.However,classmethodscanstillmodifyclassstatethatappliesacrossallinstancesoftheclass. StaticMethods Thethirdmethod,MyClass.staticmethodwasmarkedwitha@staticmethoddecoratortoflagitasastaticmethod. Thistypeofmethodtakesneitheraselfnoraclsparameter(butofcourseit’sfreetoacceptanarbitrarynumberofotherparameters). Thereforeastaticmethodcanneithermodifyobjectstatenorclassstate.Staticmethodsarerestrictedinwhatdatatheycanaccess-andthey’reprimarilyawaytonamespaceyourmethods. Let’sSeeThemInAction! Iknowthisdiscussionhasbeenfairlytheoreticaluptothispoint.AndIbelieveit’simportantthatyoudevelopanintuitiveunderstandingforhowthesemethodtypesdifferinpractice.We’llgooversomeconcreteexamplesnow. Let’stakealookathowthesemethodsbehaveinactionwhenwecallthem.We’llstartbycreatinganinstanceoftheclassandthencallingthethreedifferentmethodsonit. MyClasswassetupinsuchawaythateachmethod’simplementationreturnsatuplecontaininginformationforustotracewhat’sgoingon—andwhichpartsoftheclassorobjectthemethodcanaccess. Here’swhathappenswhenwecallaninstancemethod: >>>>>>obj=MyClass() >>>obj.method() ('instancemethodcalled',) Thisconfirmedthatmethod(theinstancemethod)hasaccesstotheobjectinstance(printedas)viatheselfargument. Whenthemethodiscalled,Pythonreplacestheselfargumentwiththeinstanceobject,obj.Wecouldignorethesyntacticsugarofthedot-callsyntax(obj.method())andpasstheinstanceobjectmanuallytogetthesameresult: >>>>>>MyClass.method(obj) ('instancemethodcalled',) Canyouguesswhatwouldhappenifyoutriedtocallthemethodwithoutfirstcreatinganinstance? Bytheway,instancemethodscanalsoaccesstheclassitselfthroughtheself.__class__attribute.Thismakesinstancemethodspowerfulintermsofaccessrestrictions-theycanmodifystateontheobjectinstanceandontheclassitself. Let’stryouttheclassmethodnext: >>>>>>obj.classmethod() ('classmethodcalled',) Callingclassmethod()showedusitdoesn’thaveaccesstotheobject,butonlytotheobject,representingtheclassitself(everythinginPythonisanobject,evenclassesthemselves). NoticehowPythonautomaticallypassestheclassasthefirstargumenttothefunctionwhenwecallMyClass.classmethod().CallingamethodinPythonthroughthedotsyntaxtriggersthisbehavior.Theselfparameteroninstancemethodsworksthesameway. Pleasenotethatnamingtheseparametersselfandclsisjustaconvention.Youcouldjustaseasilynamethemthe_objectandthe_classandgetthesameresult.Allthatmattersisthatthey’repositionedfirstintheparameterlistforthemethod. Timetocallthestaticmethodnow: >>>>>>obj.staticmethod() 'staticmethodcalled' Didyouseehowwecalledstaticmethod()ontheobjectandwereabletodososuccessfully?Somedevelopersaresurprisedwhentheylearnthatit’spossibletocallastaticmethodonanobjectinstance. BehindthescenesPythonsimplyenforcestheaccessrestrictionsbynotpassingintheselfortheclsargumentwhenastaticmethodgetscalledusingthedotsyntax. Thisconfirmsthatstaticmethodscanneitheraccesstheobjectinstancestatenortheclassstate.Theyworklikeregularfunctionsbutbelongtotheclass’s(andeveryinstance’s)namespace. Now,let’stakealookatwhathappenswhenweattempttocallthesemethodsontheclassitself-withoutcreatinganobjectinstancebeforehand: >>>>>>MyClass.classmethod() ('classmethodcalled',) >>>MyClass.staticmethod() 'staticmethodcalled' >>>MyClass.method() TypeError:unboundmethodmethod()must becalledwithMyClassinstanceasfirst argument(gotnothinginstead) Wewereabletocallclassmethod()andstaticmethod()justfine,butattemptingtocalltheinstancemethodmethod()failedwithaTypeError. Andthisistobeexpected—thistimewedidn’tcreateanobjectinstanceandtriedcallinganinstancefunctiondirectlyontheclassblueprintitself.ThismeansthereisnowayforPythontopopulatetheselfargumentandthereforethecallfails. Thisshouldmakethedistinctionbetweenthesethreemethodtypesalittlemoreclear.ButI’mnotgoingtoleaveitatthat.InthenexttwosectionsI’llgoovertwoslightlymorerealisticexamplesforwhentousethesespecialmethodtypes. Iwillbasemyexamplesaroundthisbare-bonesPizzaclass: classPizza: def__init__(self,ingredients): self.ingredients=ingredients def__repr__(self): returnf'Pizza({self.ingredients!r})' >>>>>>Pizza(['cheese','tomatoes']) Pizza(['cheese','tomatoes']) Note:ThiscodeexampleandtheonesfurtheralonginthetutorialusePython3.6f-stringstoconstructthestringreturnedby__repr__.OnPython2andversionsofPython3before3.6you’duseadifferentstringformattingexpression,forexample: def__repr__(self): return'Pizza(%r)'%self.ingredients RemoveadsDeliciousPizzaFactoriesWith@classmethod Ifyou’vehadanyexposuretopizzaintherealworldyou’llknowthattherearemanydeliciousvariationsavailable: Pizza(['mozzarella','tomatoes']) Pizza(['mozzarella','tomatoes','ham','mushrooms']) Pizza(['mozzarella']*4) TheItaliansfiguredouttheirpizzataxonomycenturiesago,andsothesedelicioustypesofpizzasallhavetheirownnames.We’ddowelltotakeadvantageofthatandgivetheusersofourPizzaclassabetterinterfaceforcreatingthepizzaobjectstheycrave. Aniceandcleanwaytodothatisbyusingclassmethodsasfactoryfunctionsforthedifferentkindsofpizzaswecancreate: classPizza: def__init__(self,ingredients): self.ingredients=ingredients def__repr__(self): returnf'Pizza({self.ingredients!r})' @classmethod defmargherita(cls): returncls(['mozzarella','tomatoes']) @classmethod defprosciutto(cls): returncls(['mozzarella','tomatoes','ham']) NotehowI’musingtheclsargumentinthemargheritaandprosciuttofactorymethodsinsteadofcallingthePizzaconstructordirectly. ThisisatrickyoucanusetofollowtheDon’tRepeatYourself(DRY)principle.Ifwedecidetorenamethisclassatsomepointwewon’thavetorememberupdatingtheconstructornameinalloftheclassmethodfactoryfunctions. Now,whatcanwedowiththesefactorymethods?Let’strythemout: >>>>>>Pizza.margherita() Pizza(['mozzarella','tomatoes']) >>>Pizza.prosciutto() Pizza(['mozzarella','tomatoes','ham']) Asyoucansee,wecanusethefactoryfunctionstocreatenewPizzaobjectsthatareconfiguredthewaywewantthem.Theyallusethesame__init__constructorinternallyandsimplyprovideashortcutforrememberingallofthevariousingredients. Anotherwaytolookatthisuseofclassmethodsisthattheyallowyoutodefinealternativeconstructorsforyourclasses. Pythononlyallowsone__init__methodperclass.Usingclassmethodsit’spossibletoaddasmanyalternativeconstructorsasnecessary.Thiscanmaketheinterfaceforyourclassesself-documenting(toacertaindegree)andsimplifytheirusage. WhenToUseStaticMethods It’salittlemoredifficulttocomeupwithagoodexamplehere.Buttellyouwhat,I’lljustkeepstretchingthepizzaanalogythinnerandthinner…(yum!) Here’swhatIcameupwith: importmath classPizza: def__init__(self,radius,ingredients): self.radius=radius self.ingredients=ingredients def__repr__(self): return(f'Pizza({self.radius!r},' f'{self.ingredients!r})') defarea(self): returnself.circle_area(self.radius) @staticmethod defcircle_area(r): returnr**2*math.pi NowwhatdidIchangehere?First,Imodifiedtheconstructorand__repr__toacceptanextraradiusargument. Ialsoaddedanarea()instancemethodthatcalculatesandreturnsthepizza’sarea(thiswouldalsobeagoodcandidateforan@property—buthey,thisisjustatoyexample). Insteadofcalculatingtheareadirectlywithinarea(),usingthewell-knowncircleareaformula,Ifactoredthatouttoaseparatecircle_area()staticmethod. Let’stryitout! >>>>>>p=Pizza(4,['mozzarella','tomatoes']) >>>p Pizza(4,['mozzarella','tomatoes']) >>>p.area() 50.26548245743669 >>>Pizza.circle_area(4) 50.26548245743669 Sure,thisisabitofasimplisticexample,butit’lldoalrighthelpingexplainsomeofthebenefitsthatstaticmethodsprovide. Aswe’velearned,staticmethodscan’taccessclassorinstancestatebecausetheydon’ttakeaclsorselfargument.That’sabiglimitation—butit’salsoagreatsignaltoshowthataparticularmethodisindependentfromeverythingelsearoundit. Intheaboveexample,it’sclearthatcircle_area()can’tmodifytheclassortheclassinstanceinanyway.(Sure,youcouldalwaysworkaroundthatwithaglobalvariablebutthat’snotthepointhere.) Now,whyisthatuseful? Flaggingamethodasastaticmethodisnotjustahintthatamethodwon’tmodifyclassorinstancestate—thisrestrictionisalsoenforcedbythePythonruntime. Techniqueslikethatallowyoutocommunicateclearlyaboutpartsofyourclassarchitecturesothatnewdevelopmentworkisnaturallyguidedtohappenwithinthesesetboundaries.Ofcourse,itwouldbeeasyenoughtodefytheserestrictions.Butinpracticetheyoftenhelpavoidaccidentalmodificationsgoingagainsttheoriginaldesign. Putdifferently,usingstaticmethodsandclassmethodsarewaystocommunicatedeveloperintentwhileenforcingthatintentenoughtoavoidmostslipofthemindmistakesandbugsthatwouldbreakthedesign. Appliedsparinglyandwhenitmakessense,writingsomeofyourmethodsthatwaycanprovidemaintenancebenefitsandmakeitlesslikelythatotherdevelopersuseyourclassesincorrectly. Staticmethodsalsohavebenefitswhenitcomestowritingtestcode. Becausethecircle_area()methodiscompletelyindependentfromtherestoftheclassit’smucheasiertotest. Wedon’thavetoworryaboutsettingupacompleteclassinstancebeforewecantestthemethodinaunittest.Wecanjustfireawaylikewewouldtestingaregularfunction.Again,thismakesfuturemaintenanceeasier. RemoveadsKeyTakeaways Instancemethodsneedaclassinstanceandcanaccesstheinstancethroughself. Classmethodsdon’tneedaclassinstance.Theycan’taccesstheinstance(self)buttheyhaveaccesstotheclassitselfviacls. Staticmethodsdon’thaveaccesstoclsorself.Theyworklikeregularfunctionsbutbelongtotheclass’snamespace. Staticandclassmethodscommunicateand(toacertaindegree)enforcedeveloperintentaboutclassdesign.Thiscanhavemaintenancebenefits. MarkasCompleted WatchNowThistutorialhasarelatedvideocoursecreatedbytheRealPythonteam.Watchittogetherwiththewrittentutorialtodeepenyourunderstanding:OOPMethodTypesinPython:@classmethodvs@staticmethodvsInstanceMethods 🐍PythonTricks💌 Getashort&sweetPythonTrickdeliveredtoyourinboxeverycoupleofdays.Nospamever.Unsubscribeanytime.CuratedbytheRealPythonteam. SendMePythonTricks» AboutDanBader DanBaderistheownerandeditorinchiefofRealPythonandthemaindeveloperoftherealpython.comlearningplatform.Danhasbeenwritingcodeformorethan20yearsandholdsamaster'sdegreeincomputerscience. »MoreaboutDan EachtutorialatRealPythoniscreatedbyateamofdeveloperssothatitmeetsourhighqualitystandards.Theteammemberswhoworkedonthistutorialare: Aldren MasterReal-WorldPythonSkillsWithUnlimitedAccesstoReal Python Joinusandgetaccesstothousandsoftutorials,hands-onvideocourses,andacommunityofexpert Pythonistas: LevelUpYourPythonSkills» MasterReal-WorldPythonSkillsWithUnlimitedAccesstoReal Python Joinusandgetaccesstothousandsoftutorials,hands-onvideocourses,andacommunityofexpertPythonistas: LevelUpYourPythonSkills» WhatDoYouThink? Ratethisarticle: Tweet Share Share Email What’syour#1takeawayorfavoritethingyoulearned?Howareyougoingtoputyournewfoundskillstouse?Leaveacommentbelowandletusknow. CommentingTips:Themostusefulcommentsarethosewrittenwiththegoaloflearningfromorhelpingoutotherstudents.Gettipsforaskinggoodquestionsandgetanswerstocommonquestionsinoursupportportal.Lookingforareal-timeconversation?VisittheRealPythonCommunityChatorjointhenext“Office Hours”LiveQ&ASession.HappyPythoning! KeepLearning RelatedTutorialCategories: intermediate python RecommendedVideoCourse:OOPMethodTypesinPython:@classmethodvs@staticmethodvsInstanceMethods KeepreadingReal Pythonbycreatingafreeaccountorsigning in: Continue» Alreadyhaveanaccount?Sign-In —FREEEmailSeries— 🐍PythonTricks💌 GetPythonTricks» 🔒Nospam.Unsubscribeanytime. AllTutorialTopics advanced api basics best-practices community databases data-science devops django docker flask front-end gamedev gui intermediate machine-learning projects python testing tools web-dev web-scraping TableofContents Instance,Class,andStaticMethods—AnOverview InstanceMethods ClassMethods StaticMethods Let’sSeeThemInAction! DeliciousPizzaFactoriesWith@classmethod WhenToUseStaticMethods KeyTakeaways MarkasCompleted Tweet Share Email RecommendedVideoCourseOOPMethodTypesinPython:@classmethodvs@staticmethodvsInstanceMethods Almostthere!Completethisformandclickthebuttonbelowtogaininstantaccess: × Object-OrientedProgramminginPython:The7BestResources(AFreePDFCheatSheet) SendMyFreeCheatSheet» 🔒Nospam.Wetakeyourprivacyseriously.



請為這篇文章評分?