Python classes provide all the standard features of Object Oriented Programming: the class inheritance mechanism allows multiple base classes, a derived class ...
Navigation
index
modules|
next|
previous|
Python»
3.10.7Documentation»
ThePythonTutorial»
9.Classes
|
9.Classes¶
Classesprovideameansofbundlingdataandfunctionalitytogether.Creating
anewclasscreatesanewtypeofobject,allowingnewinstancesofthat
typetobemade.Eachclassinstancecanhaveattributesattachedtoitfor
maintainingitsstate.Classinstancescanalsohavemethods(definedbyits
class)formodifyingitsstate.
Comparedwithotherprogramminglanguages,Python’sclassmechanismaddsclasses
withaminimumofnewsyntaxandsemantics.Itisamixtureoftheclass
mechanismsfoundinC++andModula-3.Pythonclassesprovideallthestandard
featuresofObjectOrientedProgramming:theclassinheritancemechanismallows
multiplebaseclasses,aderivedclasscanoverrideanymethodsofitsbase
classorclasses,andamethodcancallthemethodofabaseclasswiththesame
name.Objectscancontainarbitraryamountsandkindsofdata.Asistruefor
modules,classespartakeofthedynamicnatureofPython:theyarecreatedat
runtime,andcanbemodifiedfurtheraftercreation.
InC++terminology,normallyclassmembers(includingthedatamembers)are
public(exceptseebelowPrivateVariables),andallmemberfunctionsare
virtual.AsinModula-3,therearenoshorthandsforreferencingtheobject’s
membersfromitsmethods:themethodfunctionisdeclaredwithanexplicitfirst
argumentrepresentingtheobject,whichisprovidedimplicitlybythecall.As
inSmalltalk,classesthemselvesareobjects.Thisprovidessemanticsfor
importingandrenaming.UnlikeC++andModula-3,built-intypescanbeusedas
baseclassesforextensionbytheuser.Also,likeinC++,mostbuilt-in
operatorswithspecialsyntax(arithmeticoperators,subscriptingetc.)canbe
redefinedforclassinstances.
(Lackinguniversallyacceptedterminologytotalkaboutclasses,Iwillmake
occasionaluseofSmalltalkandC++terms.IwoulduseModula-3terms,since
itsobject-orientedsemanticsareclosertothoseofPythonthanC++,butI
expectthatfewreadershaveheardofit.)
9.1.AWordAboutNamesandObjects¶
Objectshaveindividuality,andmultiplenames(inmultiplescopes)canbebound
tothesameobject.Thisisknownasaliasinginotherlanguages.Thisis
usuallynotappreciatedonafirstglanceatPython,andcanbesafelyignored
whendealingwithimmutablebasictypes(numbers,strings,tuples).However,
aliasinghasapossiblysurprisingeffectonthesemanticsofPythoncode
involvingmutableobjectssuchaslists,dictionaries,andmostothertypes.
Thisisusuallyusedtothebenefitoftheprogram,sincealiasesbehavelike
pointersinsomerespects.Forexample,passinganobjectischeapsinceonlya
pointerispassedbytheimplementation;andifafunctionmodifiesanobject
passedasanargument,thecallerwillseethechange—thiseliminatesthe
needfortwodifferentargumentpassingmechanismsasinPascal.
9.2.PythonScopesandNamespaces¶
Beforeintroducingclasses,IfirsthavetotellyousomethingaboutPython’s
scoperules.Classdefinitionsplaysomeneattrickswithnamespaces,andyou
needtoknowhowscopesandnamespacesworktofullyunderstandwhat’sgoingon.
Incidentally,knowledgeaboutthissubjectisusefulforanyadvancedPython
programmer.
Let’sbeginwithsomedefinitions.
Anamespaceisamappingfromnamestoobjects.Mostnamespacesarecurrently
implementedasPythondictionaries,butthat’snormallynotnoticeableinany
way(exceptforperformance),anditmaychangeinthefuture.Examplesof
namespacesare:thesetofbuilt-innames(containingfunctionssuchasabs(),and
built-inexceptionnames);theglobalnamesinamodule;andthelocalnamesin
afunctioninvocation.Inasensethesetofattributesofanobjectalsoform
anamespace.Theimportantthingtoknowaboutnamespacesisthatthereis
absolutelynorelationbetweennamesindifferentnamespaces;forinstance,two
differentmodulesmaybothdefineafunctionmaximizewithoutconfusion—
usersofthemodulesmustprefixitwiththemodulename.
Bytheway,Iusethewordattributeforanynamefollowingadot—for
example,intheexpressionz.real,realisanattributeoftheobject
z.Strictlyspeaking,referencestonamesinmodulesareattribute
references:intheexpressionmodname.funcname,modnameisamodule
objectandfuncnameisanattributeofit.Inthiscasetherehappenstobe
astraightforwardmappingbetweenthemodule’sattributesandtheglobalnames
definedinthemodule:theysharethesamenamespace!1
Attributesmayberead-onlyorwritable.Inthelattercase,assignmentto
attributesispossible.Moduleattributesarewritable:youcanwrite
modname.the_answer=42.Writableattributesmayalsobedeletedwiththe
delstatement.Forexample,delmodname.the_answerwillremove
theattributethe_answerfromtheobjectnamedbymodname.
Namespacesarecreatedatdifferentmomentsandhavedifferentlifetimes.The
namespacecontainingthebuilt-innamesiscreatedwhenthePythoninterpreter
startsup,andisneverdeleted.Theglobalnamespaceforamoduleiscreated
whenthemoduledefinitionisreadin;normally,modulenamespacesalsolast
untiltheinterpreterquits.Thestatementsexecutedbythetop-level
invocationoftheinterpreter,eitherreadfromascriptfileorinteractively,
areconsideredpartofamodulecalled__main__,sotheyhavetheirown
globalnamespace.(Thebuilt-innamesactuallyalsoliveinamodule;thisis
calledbuiltins.)
Thelocalnamespaceforafunctioniscreatedwhenthefunctioniscalled,and
deletedwhenthefunctionreturnsorraisesanexceptionthatisnothandled
withinthefunction.(Actually,forgettingwouldbeabetterwaytodescribe
whatactuallyhappens.)Ofcourse,recursiveinvocationseachhavetheirown
localnamespace.
AscopeisatextualregionofaPythonprogramwhereanamespaceisdirectly
accessible.“Directlyaccessible”heremeansthatanunqualifiedreferencetoa
nameattemptstofindthenameinthenamespace.
Althoughscopesaredeterminedstatically,theyareuseddynamically.Atany
timeduringexecution,thereare3or4nestedscopeswhosenamespacesare
directlyaccessible:
theinnermostscope,whichissearchedfirst,containsthelocalnames
thescopesofanyenclosingfunctions,whicharesearchedstartingwiththe
nearestenclosingscope,containsnon-local,butalsonon-globalnames
thenext-to-lastscopecontainsthecurrentmodule’sglobalnames
theoutermostscope(searchedlast)isthenamespacecontainingbuilt-innames
Ifanameisdeclaredglobal,thenallreferencesandassignmentsgodirectlyto
themiddlescopecontainingthemodule’sglobalnames.Torebindvariables
foundoutsideoftheinnermostscope,thenonlocalstatementcanbe
used;ifnotdeclarednonlocal,thosevariablesareread-only(anattemptto
writetosuchavariablewillsimplycreateanewlocalvariableinthe
innermostscope,leavingtheidenticallynamedoutervariableunchanged).
Usually,thelocalscopereferencesthelocalnamesofthe(textually)current
function.Outsidefunctions,thelocalscopereferencesthesamenamespaceas
theglobalscope:themodule’snamespace.Classdefinitionsplaceyetanother
namespaceinthelocalscope.
Itisimportanttorealizethatscopesaredeterminedtextually:theglobal
scopeofafunctiondefinedinamoduleisthatmodule’snamespace,nomatter
fromwhereorbywhataliasthefunctioniscalled.Ontheotherhand,the
actualsearchfornamesisdonedynamically,atruntime—however,the
languagedefinitionisevolvingtowardsstaticnameresolution,at“compile”
time,sodon’trelyondynamicnameresolution!(Infact,localvariablesare
alreadydeterminedstatically.)
AspecialquirkofPythonisthat–ifnoglobalornonlocal
statementisineffect–assignmentstonamesalwaysgointotheinnermostscope.
Assignmentsdonotcopydata—theyjustbindnamestoobjects.Thesameistrue
fordeletions:thestatementdelxremovesthebindingofxfromthe
namespacereferencedbythelocalscope.Infact,alloperationsthatintroduce
newnamesusethelocalscope:inparticular,importstatementsand
functiondefinitionsbindthemoduleorfunctionnameinthelocalscope.
Theglobalstatementcanbeusedtoindicatethatparticular
variablesliveintheglobalscopeandshouldbereboundthere;the
nonlocalstatementindicatesthatparticularvariableslivein
anenclosingscopeandshouldbereboundthere.
9.2.1.ScopesandNamespacesExample¶
Thisisanexampledemonstratinghowtoreferencethedifferentscopesand
namespaces,andhowglobalandnonlocalaffectvariable
binding:
defscope_test():
defdo_local():
spam="localspam"
defdo_nonlocal():
nonlocalspam
spam="nonlocalspam"
defdo_global():
globalspam
spam="globalspam"
spam="testspam"
do_local()
print("Afterlocalassignment:",spam)
do_nonlocal()
print("Afternonlocalassignment:",spam)
do_global()
print("Afterglobalassignment:",spam)
scope_test()
print("Inglobalscope:",spam)
Theoutputoftheexamplecodeis:
Afterlocalassignment:testspam
Afternonlocalassignment:nonlocalspam
Afterglobalassignment:nonlocalspam
Inglobalscope:globalspam
Notehowthelocalassignment(whichisdefault)didn’tchangescope_test's
bindingofspam.Thenonlocalassignmentchangedscope_test's
bindingofspam,andtheglobalassignmentchangedthemodule-level
binding.
Youcanalsoseethattherewasnopreviousbindingforspambeforethe
globalassignment.
9.3.AFirstLookatClasses¶
Classesintroducealittlebitofnewsyntax,threenewobjecttypes,andsome
newsemantics.
9.3.1.ClassDefinitionSyntax¶
Thesimplestformofclassdefinitionlookslikethis:
classClassName:
.
.
.
Classdefinitions,likefunctiondefinitions(defstatements)mustbe
executedbeforetheyhaveanyeffect.(Youcouldconceivablyplaceaclass
definitioninabranchofanifstatement,orinsideafunction.)
Inpractice,thestatementsinsideaclassdefinitionwillusuallybefunction
definitions,butotherstatementsareallowed,andsometimesuseful—we’ll
comebacktothislater.Thefunctiondefinitionsinsideaclassnormallyhave
apeculiarformofargumentlist,dictatedbythecallingconventionsfor
methods—again,thisisexplainedlater.
Whenaclassdefinitionisentered,anewnamespaceiscreated,andusedasthe
localscope—thus,allassignmentstolocalvariablesgointothisnew
namespace.Inparticular,functiondefinitionsbindthenameofthenew
functionhere.
Whenaclassdefinitionisleftnormally(viatheend),aclassobjectis
created.Thisisbasicallyawrapperaroundthecontentsofthenamespace
createdbytheclassdefinition;we’lllearnmoreaboutclassobjectsinthe
nextsection.Theoriginallocalscope(theoneineffectjustbeforetheclass
definitionwasentered)isreinstated,andtheclassobjectisboundheretothe
classnamegivenintheclassdefinitionheader(ClassNameinthe
example).
9.3.2.ClassObjects¶
Classobjectssupporttwokindsofoperations:attributereferencesand
instantiation.
Attributereferencesusethestandardsyntaxusedforallattributereferences
inPython:obj.name.Validattributenamesareallthenamesthatwerein
theclass’snamespacewhentheclassobjectwascreated.So,iftheclass
definitionlookedlikethis:
classMyClass:
"""Asimpleexampleclass"""
i=12345
deff(self):
return'helloworld'
thenMyClass.iandMyClass.farevalidattributereferences,returning
anintegerandafunctionobject,respectively.Classattributescanalsobe
assignedto,soyoucanchangethevalueofMyClass.ibyassignment.
__doc__isalsoavalidattribute,returningthedocstringbelongingto
theclass:"Asimpleexampleclass".
Classinstantiationusesfunctionnotation.Justpretendthattheclass
objectisaparameterlessfunctionthatreturnsanewinstanceoftheclass.
Forexample(assumingtheaboveclass):
x=MyClass()
createsanewinstanceoftheclassandassignsthisobjecttothelocal
variablex.
Theinstantiationoperation(“calling”aclassobject)createsanemptyobject.
Manyclassesliketocreateobjectswithinstancescustomizedtoaspecific
initialstate.Thereforeaclassmaydefineaspecialmethodnamed
__init__(),likethis:
def__init__(self):
self.data=[]
Whenaclassdefinesan__init__()method,classinstantiation
automaticallyinvokes__init__()forthenewlycreatedclassinstance.So
inthisexample,anew,initializedinstancecanbeobtainedby:
x=MyClass()
Ofcourse,the__init__()methodmayhaveargumentsforgreater
flexibility.Inthatcase,argumentsgiventotheclassinstantiationoperator
arepassedonto__init__().Forexample,
>>>classComplex:
...def__init__(self,realpart,imagpart):
...self.r=realpart
...self.i=imagpart
...
>>>x=Complex(3.0,-4.5)
>>>x.r,x.i
(3.0,-4.5)
9.3.3.InstanceObjects¶
Nowwhatcanwedowithinstanceobjects?Theonlyoperationsunderstoodby
instanceobjectsareattributereferences.Therearetwokindsofvalid
attributenames:dataattributesandmethods.
dataattributescorrespondto“instancevariables”inSmalltalk,andto“data
members”inC++.Dataattributesneednotbedeclared;likelocalvariables,
theyspringintoexistencewhentheyarefirstassignedto.Forexample,if
xistheinstanceofMyClasscreatedabove,thefollowingpieceof
codewillprintthevalue16,withoutleavingatrace:
x.counter=1
whilex.counter<10:
x.counter=x.counter*2
print(x.counter)
delx.counter
Theotherkindofinstanceattributereferenceisamethod.Amethodisa
functionthat“belongsto”anobject.(InPython,thetermmethodisnotunique
toclassinstances:otherobjecttypescanhavemethodsaswell.Forexample,
listobjectshavemethodscalledappend,insert,remove,sort,andsoon.
However,inthefollowingdiscussion,we’llusethetermmethodexclusivelyto
meanmethodsofclassinstanceobjects,unlessexplicitlystatedotherwise.)
Validmethodnamesofaninstanceobjectdependonitsclass.Bydefinition,
allattributesofaclassthatarefunctionobjectsdefinecorresponding
methodsofitsinstances.Soinourexample,x.fisavalidmethod
reference,sinceMyClass.fisafunction,butx.iisnot,since
MyClass.iisnot.Butx.fisnotthesamethingasMyClass.f—it
isamethodobject,notafunctionobject.
9.3.4.MethodObjects¶
Usually,amethodiscalledrightafteritisbound:
x.f()
IntheMyClassexample,thiswillreturnthestring'helloworld'.
However,itisnotnecessarytocallamethodrightaway:x.fisamethod
object,andcanbestoredawayandcalledatalatertime.Forexample:
xf=x.f
whileTrue:
print(xf())
willcontinuetoprinthelloworlduntiltheendoftime.
Whatexactlyhappenswhenamethodiscalled?Youmayhavenoticedthat
x.f()wascalledwithoutanargumentabove,eventhoughthefunction
definitionforf()specifiedanargument.Whathappenedtotheargument?
SurelyPythonraisesanexceptionwhenafunctionthatrequiresanargumentis
calledwithoutany—eveniftheargumentisn’tactuallyused…
Actually,youmayhaveguessedtheanswer:thespecialthingaboutmethodsis
thattheinstanceobjectispassedasthefirstargumentofthefunction.Inour
example,thecallx.f()isexactlyequivalenttoMyClass.f(x).In
general,callingamethodwithalistofnargumentsisequivalenttocalling
thecorrespondingfunctionwithanargumentlistthatiscreatedbyinserting
themethod’sinstanceobjectbeforethefirstargument.
Ifyoustilldon’tunderstandhowmethodswork,alookattheimplementationcan
perhapsclarifymatters.Whenanon-dataattributeofaninstanceis
referenced,theinstance’sclassissearched.Ifthenamedenotesavalidclass
attributethatisafunctionobject,amethodobjectiscreatedbypacking
(pointersto)theinstanceobjectandthefunctionobjectjustfoundtogetherin
anabstractobject:thisisthemethodobject.Whenthemethodobjectiscalled
withanargumentlist,anewargumentlistisconstructedfromtheinstance
objectandtheargumentlist,andthefunctionobjectiscalledwiththisnew
argumentlist.
9.3.5.ClassandInstanceVariables¶
Generallyspeaking,instancevariablesarefordatauniquetoeachinstance
andclassvariablesareforattributesandmethodssharedbyallinstances
oftheclass:
classDog:
kind='canine'#classvariablesharedbyallinstances
def__init__(self,name):
self.name=name#instancevariableuniquetoeachinstance
>>>d=Dog('Fido')
>>>e=Dog('Buddy')
>>>d.kind#sharedbyalldogs
'canine'
>>>e.kind#sharedbyalldogs
'canine'
>>>d.name#uniquetod
'Fido'
>>>e.name#uniquetoe
'Buddy'
AsdiscussedinAWordAboutNamesandObjects,shareddatacanhavepossiblysurprising
effectswithinvolvingmutableobjectssuchaslistsanddictionaries.
Forexample,thetrickslistinthefollowingcodeshouldnotbeusedasa
classvariablebecausejustasinglelistwouldbesharedbyallDog
instances:
classDog:
tricks=[]#mistakenuseofaclassvariable
def__init__(self,name):
self.name=name
defadd_trick(self,trick):
self.tricks.append(trick)
>>>d=Dog('Fido')
>>>e=Dog('Buddy')
>>>d.add_trick('rollover')
>>>e.add_trick('playdead')
>>>d.tricks#unexpectedlysharedbyalldogs
['rollover','playdead']
Correctdesignoftheclassshoulduseaninstancevariableinstead:
classDog:
def__init__(self,name):
self.name=name
self.tricks=[]#createsanewemptylistforeachdog
defadd_trick(self,trick):
self.tricks.append(trick)
>>>d=Dog('Fido')
>>>e=Dog('Buddy')
>>>d.add_trick('rollover')
>>>e.add_trick('playdead')
>>>d.tricks
['rollover']
>>>e.tricks
['playdead']
9.4.RandomRemarks¶
Ifthesameattributenameoccursinbothaninstanceandinaclass,
thenattributelookupprioritizestheinstance:
>>>classWarehouse:
...purpose='storage'
...region='west'
...
>>>w1=Warehouse()
>>>print(w1.purpose,w1.region)
storagewest
>>>w2=Warehouse()
>>>w2.region='east'
>>>print(w2.purpose,w2.region)
storageeast
Dataattributesmaybereferencedbymethodsaswellasbyordinaryusers
(“clients”)ofanobject.Inotherwords,classesarenotusabletoimplement
pureabstractdatatypes.Infact,nothinginPythonmakesitpossibleto
enforcedatahiding—itisallbaseduponconvention.(Ontheotherhand,
thePythonimplementation,writteninC,cancompletelyhideimplementation
detailsandcontrolaccesstoanobjectifnecessary;thiscanbeusedby
extensionstoPythonwritteninC.)
Clientsshouldusedataattributeswithcare—clientsmaymessupinvariants
maintainedbythemethodsbystampingontheirdataattributes.Notethat
clientsmayadddataattributesoftheirowntoaninstanceobjectwithout
affectingthevalidityofthemethods,aslongasnameconflictsareavoided—
again,anamingconventioncansavealotofheadacheshere.
Thereisnoshorthandforreferencingdataattributes(orothermethods!)from
withinmethods.Ifindthatthisactuallyincreasesthereadabilityofmethods:
thereisnochanceofconfusinglocalvariablesandinstancevariableswhen
glancingthroughamethod.
Often,thefirstargumentofamethodiscalledself.Thisisnothingmore
thanaconvention:thenameselfhasabsolutelynospecialmeaningto
Python.Note,however,thatbynotfollowingtheconventionyourcodemaybe
lessreadabletootherPythonprogrammers,anditisalsoconceivablethata
classbrowserprogrammightbewrittenthatreliesuponsuchaconvention.
Anyfunctionobjectthatisaclassattributedefinesamethodforinstancesof
thatclass.Itisnotnecessarythatthefunctiondefinitionistextually
enclosedintheclassdefinition:assigningafunctionobjecttoalocal
variableintheclassisalsook.Forexample:
#Functiondefinedoutsidetheclass
deff1(self,x,y):
returnmin(x,x+y)
classC:
f=f1
defg(self):
return'helloworld'
h=g
Nowf,gandhareallattributesofclassCthatreferto
functionobjects,andconsequentlytheyareallmethodsofinstancesof
C—hbeingexactlyequivalenttog.Notethatthispractice
usuallyonlyservestoconfusethereaderofaprogram.
Methodsmaycallothermethodsbyusingmethodattributesoftheself
argument:
classBag:
def__init__(self):
self.data=[]
defadd(self,x):
self.data.append(x)
defaddtwice(self,x):
self.add(x)
self.add(x)
Methodsmayreferenceglobalnamesinthesamewayasordinaryfunctions.The
globalscopeassociatedwithamethodisthemodulecontainingits
definition.(Aclassisneverusedasaglobalscope.)Whileone
rarelyencountersagoodreasonforusingglobaldatainamethod,thereare
manylegitimateusesoftheglobalscope:foronething,functionsandmodules
importedintotheglobalscopecanbeusedbymethods,aswellasfunctionsand
classesdefinedinit.Usually,theclasscontainingthemethodisitself
definedinthisglobalscope,andinthenextsectionwe’llfindsomegood
reasonswhyamethodwouldwanttoreferenceitsownclass.
Eachvalueisanobject,andthereforehasaclass(alsocalleditstype).
Itisstoredasobject.__class__.
9.5.Inheritance¶
Ofcourse,alanguagefeaturewouldnotbeworthyofthename“class”without
supportinginheritance.Thesyntaxforaderivedclassdefinitionlookslike
this:
classDerivedClassName(BaseClassName):
.
.
.
ThenameBaseClassNamemustbedefinedinascopecontainingthe
derivedclassdefinition.Inplaceofabaseclassname,otherarbitrary
expressionsarealsoallowed.Thiscanbeuseful,forexample,whenthebase
classisdefinedinanothermodule:
classDerivedClassName(modname.BaseClassName):
Executionofaderivedclassdefinitionproceedsthesameasforabaseclass.
Whentheclassobjectisconstructed,thebaseclassisremembered.Thisis
usedforresolvingattributereferences:ifarequestedattributeisnotfound
intheclass,thesearchproceedstolookinthebaseclass.Thisruleis
appliedrecursivelyifthebaseclassitselfisderivedfromsomeotherclass.
There’snothingspecialaboutinstantiationofderivedclasses:
DerivedClassName()createsanewinstanceoftheclass.Methodreferences
areresolvedasfollows:thecorrespondingclassattributeissearched,
descendingdownthechainofbaseclassesifnecessary,andthemethodreference
isvalidifthisyieldsafunctionobject.
Derivedclassesmayoverridemethodsoftheirbaseclasses.Becausemethods
havenospecialprivilegeswhencallingothermethodsofthesameobject,a
methodofabaseclassthatcallsanothermethoddefinedinthesamebaseclass
mayendupcallingamethodofaderivedclassthatoverridesit.(ForC++
programmers:allmethodsinPythonareeffectivelyvirtual.)
Anoverridingmethodinaderivedclassmayinfactwanttoextendratherthan
simplyreplacethebaseclassmethodofthesamename.Thereisasimplewayto
callthebaseclassmethoddirectly:justcallBaseClassName.methodname(self,
arguments).Thisisoccasionallyusefultoclientsaswell.(Notethatthis
onlyworksifthebaseclassisaccessibleasBaseClassNameintheglobal
scope.)
Pythonhastwobuilt-infunctionsthatworkwithinheritance:
Useisinstance()tocheckaninstance’stype:isinstance(obj,int)
willbeTrueonlyifobj.__class__isintorsomeclass
derivedfromint.
Useissubclass()tocheckclassinheritance:issubclass(bool,int)
isTruesinceboolisasubclassofint.However,
issubclass(float,int)isFalsesincefloatisnota
subclassofint.
9.5.1.MultipleInheritance¶
Pythonsupportsaformofmultipleinheritanceaswell.Aclassdefinitionwith
multiplebaseclasseslookslikethis:
classDerivedClassName(Base1,Base2,Base3):
.
.
.
Formostpurposes,inthesimplestcases,youcanthinkofthesearchfor
attributesinheritedfromaparentclassasdepth-first,left-to-right,not
searchingtwiceinthesameclasswherethereisanoverlapinthehierarchy.
Thus,ifanattributeisnotfoundinDerivedClassName,itissearched
forinBase1,then(recursively)inthebaseclassesofBase1,
andifitwasnotfoundthere,itwassearchedforinBase2,andsoon.
Infact,itisslightlymorecomplexthanthat;themethodresolutionorder
changesdynamicallytosupportcooperativecallstosuper().This
approachisknowninsomeothermultiple-inheritancelanguagesas
call-next-methodandismorepowerfulthanthesupercallfoundin
single-inheritancelanguages.
Dynamicorderingisnecessarybecauseallcasesofmultipleinheritanceexhibit
oneormorediamondrelationships(whereatleastoneoftheparentclasses
canbeaccessedthroughmultiplepathsfromthebottommostclass).Forexample,
allclassesinheritfromobject,soanycaseofmultipleinheritance
providesmorethanonepathtoreachobject.Tokeepthebaseclasses
frombeingaccessedmorethanonce,thedynamicalgorithmlinearizesthesearch
orderinawaythatpreservestheleft-to-rightorderingspecifiedineach
class,thatcallseachparentonlyonce,andthatismonotonic(meaningthata
classcanbesubclassedwithoutaffectingtheprecedenceorderofitsparents).
Takentogether,thesepropertiesmakeitpossibletodesignreliableand
extensibleclasseswithmultipleinheritance.Formoredetail,see
https://www.python.org/download/releases/2.3/mro/.
9.6.PrivateVariables¶
“Private”instancevariablesthatcannotbeaccessedexceptfrominsidean
objectdon’texistinPython.However,thereisaconventionthatisfollowed
bymostPythoncode:anameprefixedwithanunderscore(e.g._spam)should
betreatedasanon-publicpartoftheAPI(whetheritisafunction,amethod
oradatamember).Itshouldbeconsideredanimplementationdetailandsubject
tochangewithoutnotice.
Sincethereisavaliduse-caseforclass-privatemembers(namelytoavoidname
clashesofnameswithnamesdefinedbysubclasses),thereislimitedsupportfor
suchamechanism,callednamemangling.Anyidentifieroftheform
__spam(atleasttwoleadingunderscores,atmostonetrailingunderscore)
istextuallyreplacedwith_classname__spam,whereclassnameisthe
currentclassnamewithleadingunderscore(s)stripped.Thismanglingisdone
withoutregardtothesyntacticpositionoftheidentifier,aslongasit
occurswithinthedefinitionofaclass.
Namemanglingishelpfulforlettingsubclassesoverridemethodswithout
breakingintraclassmethodcalls.Forexample:
classMapping:
def__init__(self,iterable):
self.items_list=[]
self.__update(iterable)
defupdate(self,iterable):
foriteminiterable:
self.items_list.append(item)
__update=update#privatecopyoforiginalupdate()method
classMappingSubclass(Mapping):
defupdate(self,keys,values):
#providesnewsignatureforupdate()
#butdoesnotbreak__init__()
foriteminzip(keys,values):
self.items_list.append(item)
TheaboveexamplewouldworkevenifMappingSubclassweretointroducea
__updateidentifiersinceitisreplacedwith_Mapping__updateinthe
Mappingclassand_MappingSubclass__updateintheMappingSubclass
classrespectively.
Notethatthemanglingrulesaredesignedmostlytoavoidaccidents;itstillis
possibletoaccessormodifyavariablethatisconsideredprivate.Thiscan
evenbeusefulinspecialcircumstances,suchasinthedebugger.
Noticethatcodepassedtoexec()oreval()doesnotconsiderthe
classnameoftheinvokingclasstobethecurrentclass;thisissimilartothe
effectoftheglobalstatement,theeffectofwhichislikewiserestricted
tocodethatisbyte-compiledtogether.Thesamerestrictionappliesto
getattr(),setattr()anddelattr(),aswellaswhenreferencing
__dict__directly.
9.7.OddsandEnds¶
SometimesitisusefultohaveadatatypesimilartothePascal“record”orC
“struct”,bundlingtogetherafewnameddataitems.Anemptyclassdefinition
willdonicely:
classEmployee:
pass
john=Employee()#Createanemptyemployeerecord
#Fillthefieldsoftherecord
john.name='JohnDoe'
john.dept='computerlab'
john.salary=1000
ApieceofPythoncodethatexpectsaparticularabstractdatatypecanoftenbe
passedaclassthatemulatesthemethodsofthatdatatypeinstead.For
instance,ifyouhaveafunctionthatformatssomedatafromafileobject,you
candefineaclasswithmethodsread()andreadline()thatgetthe
datafromastringbufferinstead,andpassitasanargument.
Instancemethodobjectshaveattributes,too:m.__self__istheinstance
objectwiththemethodm(),andm.__func__isthefunctionobject
correspondingtothemethod.
9.8.Iterators¶
Bynowyouhaveprobablynoticedthatmostcontainerobjectscanbeloopedover
usingaforstatement:
forelementin[1,2,3]:
print(element)
forelementin(1,2,3):
print(element)
forkeyin{'one':1,'two':2}:
print(key)
forcharin"123":
print(char)
forlineinopen("myfile.txt"):
print(line,end='')
Thisstyleofaccessisclear,concise,andconvenient.Theuseofiterators
pervadesandunifiesPython.Behindthescenes,theforstatement
callsiter()onthecontainerobject.Thefunctionreturnsaniterator
objectthatdefinesthemethod__next__()whichaccesses
elementsinthecontaineroneatatime.Whentherearenomoreelements,
__next__()raisesaStopIterationexceptionwhichtellsthe
forlooptoterminate.Youcancallthe__next__()method
usingthenext()built-infunction;thisexampleshowshowitallworks:
>>>s='abc'
>>>it=iter(s)
>>>it
>>>next(it)
'a'
>>>next(it)
'b'
>>>next(it)
'c'
>>>next(it)
Traceback(mostrecentcalllast):
File"",line1,in
next(it)
StopIteration
Havingseenthemechanicsbehindtheiteratorprotocol,itiseasytoadd
iteratorbehaviortoyourclasses.Definean__iter__()methodwhich
returnsanobjectwitha__next__()method.Iftheclass
defines__next__(),then__iter__()canjustreturnself:
classReverse:
"""Iteratorforloopingoverasequencebackwards."""
def__init__(self,data):
self.data=data
self.index=len(data)
def__iter__(self):
returnself
def__next__(self):
ifself.index==0:
raiseStopIteration
self.index=self.index-1
returnself.data[self.index]
>>>rev=Reverse('spam')
>>>iter(rev)
<__main__.reverseobjectat0x00a1db50>
>>>forcharinrev:
...print(char)
...
m
a
p
s
9.9.Generators¶
Generatorsareasimpleandpowerfultoolforcreatingiterators.They
arewrittenlikeregularfunctionsbutusetheyieldstatement
whenevertheywanttoreturndata.Eachtimenext()iscalledonit,the
generatorresumeswhereitleftoff(itremembersallthedatavaluesandwhich
statementwaslastexecuted).Anexampleshowsthatgeneratorscanbetrivially
easytocreate:
defreverse(data):
forindexinrange(len(data)-1,-1,-1):
yielddata[index]
>>>forcharinreverse('golf'):
...print(char)
...
f
l
o
g
Anythingthatcanbedonewithgeneratorscanalsobedonewithclass-based
iteratorsasdescribedintheprevioussection.Whatmakesgeneratorsso
compactisthatthe__iter__()and__next__()methods
arecreatedautomatically.
Anotherkeyfeatureisthatthelocalvariablesandexecutionstateare
automaticallysavedbetweencalls.Thismadethefunctioneasiertowriteand
muchmoreclearthananapproachusinginstancevariableslikeself.index
andself.data.
Inadditiontoautomaticmethodcreationandsavingprogramstate,when
generatorsterminate,theyautomaticallyraiseStopIteration.In
combination,thesefeaturesmakeiteasytocreateiteratorswithnomoreeffort
thanwritingaregularfunction.
9.10.GeneratorExpressions¶
Somesimplegeneratorscanbecodedsuccinctlyasexpressionsusingasyntax
similartolistcomprehensionsbutwithparenthesesinsteadofsquarebrackets.
Theseexpressionsaredesignedforsituationswherethegeneratorisusedright
awaybyanenclosingfunction.Generatorexpressionsaremorecompactbutless
versatilethanfullgeneratordefinitionsandtendtobemorememoryfriendly
thanequivalentlistcomprehensions.
Examples:
>>>sum(i*iforiinrange(10))#sumofsquares
285
>>>xvec=[10,20,30]
>>>yvec=[7,5,3]
>>>sum(x*yforx,yinzip(xvec,yvec))#dotproduct
260
>>>unique_words=set(wordforlineinpageforwordinline.split())
>>>valedictorian=max((student.gpa,student.name)forstudentingraduates)
>>>data='golf'
>>>list(data[i]foriinrange(len(data)-1,-1,-1))
['f','l','o','g']
Footnotes
1
Exceptforonething.Moduleobjectshaveasecretread-onlyattributecalled
__dict__whichreturnsthedictionaryusedtoimplementthemodule’s
namespace;thename__dict__isanattributebutnotaglobalname.
Obviously,usingthisviolatestheabstractionofnamespaceimplementation,and
shouldberestrictedtothingslikepost-mortemdebuggers.
TableofContents
9.Classes
9.1.AWordAboutNamesandObjects
9.2.PythonScopesandNamespaces
9.2.1.ScopesandNamespacesExample
9.3.AFirstLookatClasses
9.3.1.ClassDefinitionSyntax
9.3.2.ClassObjects
9.3.3.InstanceObjects
9.3.4.MethodObjects
9.3.5.ClassandInstanceVariables
9.4.RandomRemarks
9.5.Inheritance
9.5.1.MultipleInheritance
9.6.PrivateVariables
9.7.OddsandEnds
9.8.Iterators
9.9.Generators
9.10.GeneratorExpressions
Previoustopic
8.ErrorsandExceptions
Nexttopic
10.BriefTouroftheStandardLibrary
ThisPage
ReportaBug
ShowSource
Navigation
index
modules|
next|
previous|
Python»
3.10.7Documentation»
ThePythonTutorial»
9.Classes
|