A Python decorator is a function that helps to add some additional functionalities to an already defined function. In Python, everything is an ...
Home
Public
Questions
Tags
Users
Collectives
ExploreCollectives
FindaJob
Jobs
Companies
Teams
StackOverflowforTeams
–Collaborateandshareknowledgewithaprivategroup.
CreateafreeTeam
WhatisTeams?
Teams
CreatefreeTeam
CollectivesonStackOverflow
Findcentralized,trustedcontentandcollaboratearoundthetechnologiesyouusemost.
Learnmore
Teams
Q&Aforwork
Connectandshareknowledgewithinasinglelocationthatisstructuredandeasytosearch.
Learnmore
Howdoesthe@propertydecoratorworkinPython?
AskQuestion
Asked
8years,9monthsago
Modified
4daysago
Viewed
643ktimes
1210
529
Iwouldliketounderstandhowthebuilt-infunctionpropertyworks.Whatconfusesmeisthatpropertycanalsobeusedasadecorator,butitonlytakesargumentswhenusedasabuilt-infunctionandnotwhenusedasadecorator.
Thisexampleisfromthedocumentation:
classC:
def__init__(self):
self._x=None
defgetx(self):
returnself._x
defsetx(self,value):
self._x=value
defdelx(self):
delself._x
x=property(getx,setx,delx,"I'mthe'x'property.")
property'sargumentsaregetx,setx,delxandadocstring.
Inthecodebelowpropertyisusedasadecorator.Theobjectofitisthexfunction,butinthecodeabovethereisnoplaceforanobjectfunctioninthearguments.
classC:
def__init__(self):
self._x=None
@property
defx(self):
"""I'mthe'x'property."""
returnself._x
@x.setter
defx(self,value):
self._x=value
@x.deleter
defx(self):
delself._x
Howarethex.setterandx.deleterdecoratorscreatedinthiscase?
pythonpropertiesdecoratorpython-decoratorspython-internals
Share
Improvethisquestion
Follow
editedJan13,2021at23:00
Boris
9,83177goldbadges7575silverbadges7777bronzebadges
askedJun26,2013at20:47
ashimashim
22.4k2929goldbadges7070silverbadges9191bronzebadges
8
19
Seealso:HowdoPythonpropertieswork?
– MartinThoma
Feb3,2015at8:24
3
propertyisactuallyaclass(notafunction),althoughitdoesprobablydoescallthe__init__()methodwhenyoumakeanobject,ofcourse.Usinghelp(property)fromtheterminalisinsightful.helpisalsoaclassforsomereason.
– Brōtsyorfuzthrāx
Dec8,2016at8:17
2
Ithinkthislinkprovidesagoodexample:[property](journaldev.com/14893/python-property-decorator)
– ShengBi
Feb7,2019at16:55
4
@Shule2-year-oldthread,butstill:Everythingisaclass.Evenclasses.
– Artemis
Apr23,2019at20:27
3
Thiswasconfusingtometoo.Ifinallyfoundanarticlethatwasabletobreakitdownforme.Ihopethishelpssomeoneelse.programiz.com/python-programming/propertyI'mnotaffiliatedinanywaywiththesite.
– jjwdesign
Jun14,2019at17:55
|
Show3morecomments
14Answers
14
Sortedby:
Resettodefault
Highestscore(default)
Datemodified(newestfirst)
Datecreated(oldestfirst)
1185
Theproperty()functionreturnsaspecialdescriptorobject:
>>>property()
Itisthisobjectthathasextramethods:
>>>property().getter
>>>property().setter
>>>property().deleter
Theseactasdecoratorstoo.Theyreturnanewpropertyobject:
>>>property().getter(None)
thatisacopyoftheoldobject,butwithoneofthefunctionsreplaced.
Remember,thatthe@decoratorsyntaxisjustsyntacticsugar;thesyntax:
@property
deffoo(self):returnself._foo
reallymeansthesamethingas
deffoo(self):returnself._foo
foo=property(foo)
sofoothefunctionisreplacedbyproperty(foo),[email protected](),whatyouaredoingiscallthatproperty().settermethodIshowedyouabove,whichreturnsanewcopyoftheproperty,butthistimewiththesetterfunctionreplacedwiththedecoratedmethod.
Thefollowingsequencealsocreatesafull-onproperty,byusingthosedecoratormethods.
Firstwecreatesomefunctionsandapropertyobjectwithjustagetter:
>>>defgetter(self):print('Get!')
...
>>>defsetter(self,value):print('Setto{!r}!'.format(value))
...
>>>defdeleter(self):print('Delete!')
...
>>>prop=property(getter)
>>>prop.fgetisgetter
True
>>>prop.fsetisNone
True
>>>prop.fdelisNone
True
Nextweusethe.setter()methodtoaddasetter:
>>>prop=prop.setter(setter)
>>>prop.fgetisgetter
True
>>>prop.fsetissetter
True
>>>prop.fdelisNone
True
Lastweaddadeleterwiththe.deleter()method:
>>>prop=prop.deleter(deleter)
>>>prop.fgetisgetter
True
>>>prop.fsetissetter
True
>>>prop.fdelisdeleter
True
Lastbutnotleast,thepropertyobjectactsasadescriptorobject,soithas.__get__(),.__set__()and.__delete__()methodstohookintoinstanceattributegetting,settinganddeleting:
>>>classFoo:pass
...
>>>prop.__get__(Foo(),Foo)
Get!
>>>prop.__set__(Foo(),'bar')
Setto'bar'!
>>>prop.__delete__(Foo())
Delete!
TheDescriptorHowtoincludesapurePythonsampleimplementationoftheproperty()type:
classProperty:
"EmulatePyProperty_Type()inObjects/descrobject.c"
def__init__(self,fget=None,fset=None,fdel=None,doc=None):
self.fget=fget
self.fset=fset
self.fdel=fdel
ifdocisNoneandfgetisnotNone:
doc=fget.__doc__
self.__doc__=doc
def__get__(self,obj,objtype=None):
ifobjisNone:
returnself
ifself.fgetisNone:
raiseAttributeError("unreadableattribute")
returnself.fget(obj)
def__set__(self,obj,value):
ifself.fsetisNone:
raiseAttributeError("can'tsetattribute")
self.fset(obj,value)
def__delete__(self,obj):
ifself.fdelisNone:
raiseAttributeError("can'tdeleteattribute")
self.fdel(obj)
defgetter(self,fget):
returntype(self)(fget,self.fset,self.fdel,self.__doc__)
defsetter(self,fset):
returntype(self)(self.fget,fset,self.fdel,self.__doc__)
defdeleter(self,fdel):
returntype(self)(self.fget,self.fset,fdel,self.__doc__)
Share
Improvethisanswer
Follow
editedOct20,2019at19:02
Boris
9,83177goldbadges7575silverbadges7777bronzebadges
answeredJun26,2013at20:54
MartijnPieters♦MartijnPieters
949k260260goldbadges37533753silverbadges31543154bronzebadges
25
13
Verygood.YoucouldaddthefactthatafterFoo.prop=propyoucandoFoo().prop=5;prontFoo().prop;delFoo().propwiththedesiredoutcome.
– glglgl
Jun27,2013at7:25
13
Methodobjectsarecreatedontheflyandcanreusethesamememorylocationifavailable.
– MartijnPieters
♦
Jun12,2014at19:15
1
@MarkusMeskanen:Iratherusetype()asaccessingdunderattributesandmethodsaremeanttobeusedasextensionpointsbythestandardfunctionsandoperators.
– MartijnPieters
♦
Mar10,2015at21:46
2
@MarkusMeskanen:becausetheobjectisimmutable,andifyoumutateditinplaceyoucouldnotspecialiseitinasubclass.
– MartijnPieters
♦
Jun13,2015at14:25
7
@MarkusMeskanen:seePythonoverridinggetterwithoutsetter;if@human.name.getteralteredthepropertyobjectin-placeratherthanreturnanew,thehuman.nameattributewouldbealtered,changingthebehaviourofthatsuperclass.
– MartijnPieters
♦
Jun13,2015at14:33
|
Show20morecomments
293
Documentationsaysit'sjustashortcutforcreatingreadonlyproperties.So
@property
defx(self):
returnself._x
isequivalentto
defgetx(self):
returnself._x
x=property(getx)
Share
Improvethisanswer
Follow
editedJul15,2016at20:45
λuser
86688silverbadges1414bronzebadges
answeredJun26,2013at20:52
J0HNJ0HN
24.9k55goldbadges4747silverbadges8484bronzebadges
2
55
Thefullcontext(most-upvotedanswer)isgood,butthisanswerwaspracticallyusefulforfiguringoutwhysomeoneelsehadused@propertyasadecoratorintheirclass.
– ijoseph
Apr16,2019at23:23
4
"...shortcutforcreatingreadonlyproperties.".Themilliondolahanswer!
– Saptadeep
Oct27,2021at18:00
Addacomment
|
153
Hereisaminimalexampleofhow@propertycanbeimplemented:
classThing:
def__init__(self,my_word):
self._word=my_word
@property
defword(self):
returnself._word
>>>print(Thing('ok').word)
'ok'
Otherwisewordremainsamethodinsteadofaproperty.
classThing:
def__init__(self,my_word):
self._word=my_word
defword(self):
returnself._word
>>>print(Thing('ok').word())
'ok'
Share
Improvethisanswer
Follow
answeredFeb15,2017at0:46
AlexGAlexG
9,84466goldbadges5858silverbadges6868bronzebadges
4
1
Howwouldthisexamplelookiftheword()function/propertyneededtobedefinedininit?
– J.J
Apr9,2017at9:51
14
CansomeonepleaseexplainwhyIwouldcreateapropertydecoratorhere,insteadofjusthavingself.word=my_word--whichwouldthenworkthesamewayprint(Thing('ok').word)='ok'
– SilverSlash
Jun9,2017at4:41
1
@SilverSlashThisisjustasimpleexample,arealuse-casewouldinvolveamorecomplicatedmethod
– AlexG
Jun9,2017at16:22
canyoupleaseexplainme,howprintingThing('ok').wordcallsthefunctioninternallyatruntime?
– Vicrobot
Dec27,2019at13:35
Addacomment
|
90
Thefirstpartissimple:
@property
defx(self):...
isthesameas
defx(self):...
x=property(x)
which,inturn,isthesimplifiedsyntaxforcreatingapropertywithjustagetter.
Thenextstepwouldbetoextendthispropertywithasetterandadeleter.Andthishappenswiththeappropriatemethods:
@x.setter
defx(self,value):...
returnsanewpropertywhichinheritseverythingfromtheoldxplusthegivensetter.
x.deleterworksthesameway.
Share
Improvethisanswer
Follow
answeredJun26,2013at20:53
glglglglglgl
84.6k1111goldbadges137137silverbadges208208bronzebadges
Addacomment
|
84
Belowisanotherexampleonhow@propertycanhelpwhenonehastorefactorcodewhichistakenfromhere(Ionlysummarizeitbelow):
ImagineyoucreatedaclassMoneylikethis:
classMoney:
def__init__(self,dollars,cents):
self.dollars=dollars
self.cents=cents
andanusercreatesalibrarydependingonthisclasswherehe/sheusese.g.
money=Money(27,12)
print("Ihave{}dollarand{}cents.".format(money.dollars,money.cents))
#printsIhave27dollarand12cents.
Nowlet'ssupposeyoudecidetochangeyourMoneyclassandgetridofthedollarsandcentsattributesbutinsteaddecidetoonlytrackthetotalamountofcents:
classMoney:
def__init__(self,dollars,cents):
self.total_cents=dollars*100+cents
Iftheabovementionedusernowtriestorunhis/herlibraryasbefore
money=Money(27,12)
print("Ihave{}dollarand{}cents.".format(money.dollars,money.cents))
itwillresultinanerror
AttributeError:'Money'objecthasnoattribute'dollars'
ThatmeansthatnoweveryonewhoreliesonyouroriginalMoneyclasswouldhavetochangealllinesofcodewheredollarsandcentsareusedwhichcanbeverypainful...So,howcouldthisbeavoided?Byusing@property!
Thatishow:
classMoney:
def__init__(self,dollars,cents):
self.total_cents=dollars*100+cents
#Getterandsetterfordollars...
@property
defdollars(self):
returnself.total_cents//100
@dollars.setter
defdollars(self,new_dollars):
self.total_cents=100*new_dollars+self.cents
#Andthegetterandsetterforcents.
@property
defcents(self):
returnself.total_cents%100
@cents.setter
defcents(self,new_cents):
self.total_cents=100*self.dollars+new_cents
whenwenowcallfromourlibrary
money=Money(27,12)
print("Ihave{}dollarand{}cents.".format(money.dollars,money.cents))
#printsIhave27dollarand12cents.
itwillworkasexpectedandwedidnothavetochangeasinglelineofcodeinourlibrary!Infact,wewouldnotevenhavetoknowthatthelibrarywedependonchanged.
Alsothesetterworksfine:
money.dollars+=2
print("Ihave{}dollarand{}cents.".format(money.dollars,money.cents))
#printsIhave29dollarand12cents.
money.cents+=10
print("Ihave{}dollarand{}cents.".format(money.dollars,money.cents))
#printsIhave29dollarand22cents.
Youcanuse@propertyalsoinabstractclasses;Igiveaminimalexamplehere.
Share
Improvethisanswer
Follow
editedSep16,2019at21:42
answeredSep23,2018at11:58
ClebCleb
22.5k1818goldbadges100100silverbadges139139bronzebadges
4
3
yoursummaryisverygood,theexamplethatwebsitetakesisalittlebitstrange..Abeginnerwouldask..whycan'twejuststicktotheself.dollar=dollars?wehavedonesomuchwith@property,butitseemsnoextractfunctionalityisadded.
– ShengBi
Feb7,2019at16:39
4
@ShengBi:Donotfocusthatmuchontheactualexamplebutmoreontheunderlyingprinciple:If-forwhateverreason-youhavetorefactorcode,youcandosowithoutaffectinganyoneother'scode.
– Cleb
Feb7,2019at16:44
1
@clebyoudarealmvp.Everybodyelseusesthatgettersetterexamplelikethisone,programiz.com/python-programming/property.Butyouaretheonlyonethatactuallyexplainswhywewantproperty.It'sbecausewhenwewritessomethinguponwhichalotofpeoplearegoingtobuild,wewanttobeabletomodifythebaseclasseswithoutnorealimpactonhowthesuccessorsuseorbuilduponourwork,implementationwise.
– ChenLizi
Apr7,2021at0:28
1
@ClebIsuredid!:)
– ChenLizi
Apr7,2021at17:27
Addacomment
|
58
Thisfollowing:
classC(object):
def__init__(self):
self._x=None
@property
defx(self):
"""I'mthe'x'property."""
returnself._x
@x.setter
defx(self,value):
self._x=value
@x.deleter
defx(self):
delself._x
Isthesameas:
classC(object):
def__init__(self):
self._x=None
def_x_get(self):
returnself._x
def_x_set(self,value):
self._x=value
def_x_del(self):
delself._x
x=property(_x_get,_x_set,_x_del,
"I'mthe'x'property.")
Isthesameas:
classC(object):
def__init__(self):
self._x=None
def_x_get(self):
returnself._x
def_x_set(self,value):
self._x=value
def_x_del(self):
delself._x
x=property(_x_get,doc="I'mthe'x'property.")
x=x.setter(_x_set)
x=x.deleter(_x_del)
Isthesameas:
classC(object):
def__init__(self):
self._x=None
def_x_get(self):
returnself._x
x=property(_x_get,doc="I'mthe'x'property.")
def_x_set(self,value):
self._x=value
x=x.setter(_x_set)
def_x_del(self):
delself._x
x=x.deleter(_x_del)
Whichisthesameas:
classC(object):
def__init__(self):
self._x=None
@property
defx(self):
"""I'mthe'x'property."""
returnself._x
@x.setter
defx(self,value):
self._x=value
@x.deleter
defx(self):
delself._x
Share
Improvethisanswer
Follow
answeredMay24,2017at18:38
BimoBimo
5,01311goldbadge3131silverbadges4848bronzebadges
2
5
Thefirstandlastcodeexamplesarethesame(verbatim).
– AdomasBaliuka
Aug15,2019at2:13
2
Ithinkit'sintentional.Eitherway,thiswasthemostusefulexampletomebecauseIcangrokmeaningfromtheseexamples.Thanks@BillMoore
– Jérémie
Jun14,2020at16:20
Addacomment
|
36
Let'sstartwithPythondecorators.
APythondecoratorisafunctionthathelpstoaddsomeadditionalfunctionalitiestoanalreadydefinedfunction.
InPython,everythingisanobject.FunctionsinPythonarefirst-classobjectswhichmeansthattheycanbereferencedbyavariable,addedinthelists,passedasargumentstoanotherfunction,etc.
Considerthefollowingcodesnippet.
defdecorator_func(fun):
defwrapper_func():
print("Wrapperfunctionstarted")
fun()
print("Givenfunctiondecorated")
#Wrapperfunctionaddsomethingtothepassedfunctionanddecorator
#returnsthewrapperfunction
returnwrapper_func
defsay_bye():
print("bye!!")
say_bye=decorator_func(say_bye)
say_bye()
#Output:
#Wrapperfunctionstarted
#bye!!
#Givenfunctiondecorated
Here,wecansaythatthedecoratorfunctionmodifiedoursay_byefunctionandaddedsomeextralinesofcodetoit.
Pythonsyntaxfordecorator
defdecorator_func(fun):
defwrapper_func():
print("Wrapperfunctionstarted")
fun()
print("Givenfunctiondecorated")
#Wrapperfunctionaddsomethingtothepassedfunctionanddecorator
#returnsthewrapperfunction
returnwrapper_func
@decorator_func
defsay_bye():
print("bye!!")
say_bye()
Let'sgothrougheverythingwithacasescenario.Butbeforethat,let'stalkaboutsomeOOPprinciples.
Gettersandsettersareusedinmanyobject-orientedprogramminglanguagestoensuretheprincipleofdataencapsulation(whichisseenasthebundlingofdatawiththemethodsthatoperateonthesedata.)
Thesemethodsare,ofcourse,thegetterforretrievingthedataandthesetterforchangingthedata.
Accordingtothisprinciple,theattributesofaclassaremadeprivatetohideandprotectthemfromothercode.
Yup,@propertyisbasicallyapythonicwaytousegettersandsetters.
Pythonhasagreatconceptcalledpropertywhichmakesthelifeofanobject-orientedprogrammermuchsimpler.
LetusassumethatyoudecidetomakeaclassthatcouldstorethetemperatureindegreesCelsius.
classCelsius:
def__init__(self,temperature=0):
self.set_temperature(temperature)
defto_fahrenheit(self):
return(self.get_temperature()*1.8)+32
defget_temperature(self):
returnself._temperature
defset_temperature(self,value):
ifvalue1000:
self.__x=1000
else:
self.__x=x
Thisisgreat,isn'tit:Youcanstartwiththesimplestimplementationimaginable,andyouarefreetolatermigratetoapropertyversionwithouthavingtochangetheinterface!Sopropertiesarenotjustareplacementforgettersandsetters!
YoucancheckthisImplementationhere
Share
Improvethisanswer
Follow
editedJul23,2021at9:25
Useless
59.1k55goldbadges7979silverbadges123123bronzebadges
answeredSep17,2018at0:01
DivyanshuRawatDivyanshuRawat
3,47111goldbadge3232silverbadges4141bronzebadges
7
7
YourCelsiusclassisgoingtoinfinitelyrecursewhensetting(whichmeansuponinstantiation).
– TedPetrou
Sep23,2018at12:25
1
@TedPetrouIDidn'tgetyou?Howitwillinfinitelyrecursewhensetting?
– DivyanshuRawat
Sep23,2018at12:37
1
Peopleareaskinghowdoesitworknotwhyitworks?@ShengBi
– DivyanshuRawat
Feb7,2019at17:53
1
Itisjustacomment,mypersonalopinion.Youranswercouldbereallygood.soleaveit.
– ShengBi
Feb10,2019at1:14
2
comparedtothetopvotedanswers,thisoneisdesignedforhumans;thanks.
– Info5ek
May18,2020at0:06
|
Show2morecomments
28
Ireadallthepostshereandrealizedthatwemayneedareallifeexample.Why,actually,wehave@property?
So,consideraFlaskappwhereyouuseauthenticationsystem.
YoudeclareamodelUserinmodels.py:
classUser(UserMixin,db.Model):
__tablename__='users'
id=db.Column(db.Integer,primary_key=True)
email=db.Column(db.String(64),unique=True,index=True)
username=db.Column(db.String(64),unique=True,index=True)
password_hash=db.Column(db.String(128))
...
@property
defpassword(self):
raiseAttributeError('passwordisnotareadableattribute')
@password.setter
defpassword(self,password):
self.password_hash=generate_password_hash(password)
defverify_password(self,password):
returncheck_password_hash(self.password_hash,password)
Inthiscodewe've"hidden"attributepasswordbyusing@propertywhichtriggersAttributeErrorassertionwhenyoutrytoaccessitdirectly,whileweused@property.settertosettheactualinstancevariablepassword_hash.
Nowinauth/views.pywecaninstantiateaUserwith:
...
@auth.route('/register',methods=['GET','POST'])
defregister():
form=RegisterForm()
ifform.validate_on_submit():
user=User(email=form.email.data,
username=form.username.data,
password=form.password.data)
db.session.add(user)
db.session.commit()
...
Noticeattributepasswordthatcomesfromaregistrationformwhenauserfillstheform.PasswordconfirmationhappensonthefrontendwithEqualTo('password',message='Passwordsmustmatch')(incaseifyouarewondering,butit'sadifferenttopicrelatedFlaskforms).
Ihopethisexamplewillbeuseful
Share
Improvethisanswer
Follow
editedSep10,2019at15:24
answeredMar23,2018at14:47
LeoSkhrnkvLeoSkhrnkv
1,2551515silverbadges2525bronzebadges
Addacomment
|
18
ThispointisbeenclearedbymanypeopleuptherebuthereisadirectpointwhichIwassearching.
ThisiswhatIfeelisimportanttostartwiththe@propertydecorator.
eg:-
classUtilityMixin():
@property
defget_config(self):
return"Thisisproperty"
Thecallingoffunction"get_config()"willworklikethis.
util=UtilityMixin()
print(util.get_config)
IfyounoticeIhavenotused"()"bracketsforcallingthefunction.ThisisthebasicthingwhichIwassearchingforthe@propertydecorator.Sothatyoucanuseyourfunctionjustlikeavariable.
Share
Improvethisanswer
Follow
editedNov26,2018at6:39
answeredNov9,2018at13:00
DevendraBhatDevendraBhat
1,04111goldbadge1313silverbadges1919bronzebadges
0
Addacomment
|
8
propertyisaclassbehind@propertydecorator.
Youcanalwayscheckthis:
print(property)#
Irewrotetheexamplefromhelp(property)toshowthatthe@propertysyntax
classC:
def__init__(self):
self._x=None
@property
defx(self):
returnself._x
@x.setter
defx(self,value):
self._x=value
@x.deleter
defx(self):
delself._x
c=C()
c.x="a"
print(c.x)
isfunctionallyidenticaltoproperty()syntax:
classC:
def__init__(self):
self._x=None
defg(self):
returnself._x
defs(self,v):
self._x=v
defd(self):
delself._x
prop=property(g,s,d)
c=C()
c.x="a"
print(c.x)
Thereisnodifferencehowweusethepropertyasyoucansee.
Toanswerthequestion@propertydecoratorisimplementedviapropertyclass.
So,thequestionistoexplainthepropertyclassabit.
Thisline:
prop=property(g,s,d)
Wastheinitialization.Wecanrewriteitlikethis:
prop=property(fget=g,fset=s,fdel=d)
Themeaningoffget,fsetandfdel:
|fget
|functiontobeusedforgettinganattributevalue
|fset
|functiontobeusedforsettinganattributevalue
|fdel
|functiontobeusedfordel'inganattribute
|doc
|docstring
Thenextimageshowsthetripletswehave,fromtheclassproperty:
__get__,__set__,and__delete__aretheretobeoverridden.ThisistheimplementationofthedescriptorpatterninPython.
Ingeneral,adescriptorisanobjectattributewith“bindingbehavior”,onewhoseattributeaccesshasbeenoverriddenbymethodsinthedescriptorprotocol.
Wecanalsousepropertysetter,getteranddeletermethodstobindthefunctiontoproperty.Checkthenextexample.Themethods2oftheclassCwillsetthepropertydoubled.
classC:
def__init__(self):
self._x=None
defg(self):
returnself._x
defs(self,x):
self._x=x
defd(self):
delself._x
defs2(self,x):
self._x=x+x
x=property(g)
x=x.setter(s)
x=x.deleter(d)
c=C()
c.x="a"
print(c.x)#outputs"a"
C.x=property(C.g,C.s2)
C.x=C.x.deleter(C.d)
c2=C()
c2.x="a"
print(c2.x)#outputs"aa"
Share
Improvethisanswer
Follow
editedMay26,2019at21:10
answeredMay26,2019at16:27
prostiprosti
34k99goldbadges157157silverbadges139139bronzebadges
Addacomment
|
8
Thebestexplanationcanbefoundhere:
Python@PropertyExplained–HowtoUseandWhen?(FullExamples)
bySelvaPrabhakaran|PostedonNovember5,2018
IthelpedmeunderstandWHYnotonlyHOW.
https://www.machinelearningplus.com/python/python-property/
Share
Improvethisanswer
Follow
editedFeb25,2020at3:50
answeredFeb22,2020at1:28
VictorWangVictorWang
57988silverbadges1818bronzebadges
1
Thisisthebestsourceasofnow
– thanos.a
Mar19at3:00
Addacomment
|
5
Adecoratorisafunctionthattakesafunctionasanargumentandreturnsaclosure.Theclosureisasetofinnerfunctionsandfreevariables.Theinnerfunctionisclosingoverthefreevariableandthatiswhyitiscalled'closure'.Afreevariableisavariablethatisoutsidetheinnerfunctionandpassedintotheinnerviadocorator.
Asthenamesays,decoratorisdecoratingthereceivedfunction.
functiondecorator(undecorated_func):
print("callingdecoratorfunc")
inner():
print("Iaminsideinner")
returnundecorated_func
returninner
thisisasimpledecoratorfunction.Itreceived"undecorated_func"andpassedittoinner()asafreevariable,inner()printed"Iaminsideinner"andreturnedundecorated_func.Whenwecalldecorator(undecorated_func),itisreturningtheinner.Hereisthekey,indecoratorswearenamingtheinnerfunctionasthenameofthefunctionthatwepassed.
undecorated_function=decorator(undecorated_func)
nowinnerfunctioniscalled"undecorated_func".Sinceinnerisnownamedas"undecorated_func",wepassed"undecorated_func"tothedecoratorandwereturned"undecorated_func"plusprintedout"Iaminsideinner".sothisprintstatementdecoratedour"undecorated_func".
nowlet'sdefineaclasswithapropertydecorator:
classPerson:
def__init__(self,name):
self._name=name
@property
defname(self):
returnself._name
@name.setter
defname(self.value):
self._name=value
whenwedecoratedname()with@property(),thisiswhathappened:
name=property(name)#Person.__dict__youllseename
firstargumentofproperty()isgetter.thisiswhathappenedintheseconddecoration:
name=name.setter(name)
AsImentionedabove,thedecoratorreturnstheinnerfunction,andwenametheinnerfunctionwiththenameofthefunctionthatwepassed.
Hereisanimportantthingtobeawareof."name"isimmutable.inthefirstdecorationwegotthis:
name=property(name)
inthesecondonewegotthis
name=name.setter(name)
Wearenotmodifyingnameobj.Intheseconddecoration,pythonseesthatthisispropertyobjectanditalreadyhadgetter.Sopythoncreatesanew"name"object,addsthe"fget"fromthefirstobjandthensetsthe"fset".
Share
Improvethisanswer
Follow
editedMar19at2:47
answeredNov30,2020at21:02
YilmazYilmaz
12.2k77goldbadges6464silverbadges9999bronzebadges
2
Youranswerhasalotoftyposandsytaxmistakesthatpreventedmefromreadingit.
– thanos.a
Mar19at2:44
@thanos.aIamsosorryaboutit:)IdideditedsometyposbutIdonotseeanysyntaxerror
– Yilmaz
Mar19at2:48
Addacomment
|
1
Apropertycanbedeclaredintwoways.
Creatingthegetter,settermethodsforanattributeandthenpassingtheseasargumenttopropertyfunction
Usingthe@propertydecorator.
YoucanhavealookatfewexamplesIhavewrittenaboutpropertiesinpython.
Share
Improvethisanswer
Follow
answeredJul13,2017at9:20
nvdnvd
38933silverbadges22bronzebadges
1
canyouupdatedyouranswersayingthatpropertyisaclasssoIcanupvote.
– prosti
May26,2019at21:43
Addacomment
|
0
Hereisanotherexample:
##
##PythonPropertiesExample
##
classGetterSetterExample(object):
##Setthedefaultvalueforx(wereferenceitusingself.x,setavalueusingself.x=value)
__x=None
##
##OnClassInitialization-dosomething...ifwewant..
##
def__init__(self):
##Setavalueto__xthroughthegetter/setter...Since__xisdefinedabove,thisdoesn'tneedtobeset...
self.x=1234
returnNone
##
##Definexasaproperty,ieagetter-Allgettersshouldhaveadefaultvaluearg,soIaddedit-itwillnotbepassedinwhensettingavalue,soyouneedtosetthedefaultheresoitwillbeused..
##
@property
defx(self,_default=None):
##Iaddedanoptionaldefaultvalueargumentasallgettersshouldhavethis-setittothedefaultvalueyouwanttoreturn...
_value=(self.__x,_default)[self.__x==None]
##Debugging-soyoucanseetheorderthecallsaremade...
print('[TestClass]Getx='+str(_value))
##Returnthevalue-weareagetterafterall...
return_value
##
##Definethesetterfunctionforx...
##
@x.setter
defx(self,_value=None):
##Debugging-soyoucanseetheorderthecallsaremade...
print('[TestClass]Setx='+str(_value))
##Thisistoshowthesetterfunctionworks....Ifthevalueisabove0,setittoanegativevalue...otherwisekeepitasis(0istheonlynon-negativenumber,itcan'tbenegativeorpositiveanyway)
if(_value>0):
self.__x=-_value
else:
self.__x=_value
##
##Definethedeleterfunctionforx...
##
@x.deleter
defx(self):
##Unloadtheassignment/dataforx
if(self.__x!=None):
delself.__x
##
##ToString/OutputFunctionfortheclass-thiswillshowthepropertyvalueforeachpropertyweadd...
##
def__str__(self):
##Outputthexpropertydata...
print('[x]'+str(self.x))
##Returnanewline-technicallyweshouldreturnastringsoitcanbeprintedwherewewantit,insteadofprintedearlyif_data=str(C())isused....
return'\n'
##
##
##
_test=GetterSetterExample()
print(_test)
##Forsomereasonthedeleterisn'tbeingcalled...
del_test.x
Basically,thesameastheC(object)exampleexceptI'musingxinstead...Ialsodon'tinitializein__init-...well..Ido,butitcanberemovedbecause__xisdefinedaspartoftheclass....
Theoutputis:
[TestClass]Setx=1234
[TestClass]Getx=-1234
[x]-1234
andifIcommentouttheself.x=1234ininitthentheoutputis:
[TestClass]Getx=None
[x]None
andifIsetthe_default=Noneto_default=0inthegetterfunction(asallgettersshouldhaveadefaultvaluebutitisn'tpassedinbythepropertyvaluesfromwhatI'veseensoyoucandefineithere,anditactuallyisn'tbadbecauseyoucandefinethedefaultonceanduseiteverywhere)ie:defx(self,_default=0):
[TestClass]Getx=0
[x]0
Note:Thegetterlogicistherejusttohavethevaluebemanipulatedbyittoensureitismanipulatedbyit-thesamefortheprintstatements...
Note:I'musedtoLuaandbeingabletodynamicallycreate10+helperswhenIcallasinglefunctionandImadesomethingsimilarforPythonwithoutusingpropertiesanditworkstoadegree,but,eventhoughthefunctionsarebeingcreatedbeforebeingused,therearestillissuesattimeswiththembeingcalledpriortobeingcreatedwhichisstrangeasitisn'tcodedthatway...IprefertheflexibilityofLuameta-tablesandthefactIcanuseactualsetters/gettersinsteadofessentiallydirectlyaccessingavariable...IdolikehowquicklysomethingscanbebuiltwithPythonthough-forinstanceguiprograms.althoughoneIamdesigningmaynotbepossiblewithoutalotofadditionallibraries-ifIcodeitinAutoHotkeyIcandirectlyaccessthedllcallsIneed,andthesamecanbedoneinJava,C#,C++,andmore-maybeIhaven'tfoundtherightthingyetbutforthatprojectImayswitchfromPython..
Note:Thecodeoutputinthisforumisbroken-Ihadtoaddspacestothefirstpartofthecodeforittowork-whencopy/pastingensureyouconvertallspacestotabs....IusetabsforPythonbecauseinafilewhichis10,000linesthefilesizecanbe512KBto1MBwithspacesand100to200KBwithtabswhichequatestoamassivedifferenceforfilesize,andreductioninprocessingtime...
Tabscanalsobeadjustedperuser-soifyouprefer2spaceswidth,4,8orwhateveryoucandoitmeaningitisthoughtfulfordeveloperswitheye-sightdeficits.
Note:Allofthefunctionsdefinedintheclassaren'tindentedproperlybecauseofabugintheforumsoftware-ensureyouindentitifyoucopy/paste
Share
Improvethisanswer
Follow
answeredAug7,2018at11:08
AcecoolAcecool
62488silverbadges1212bronzebadges
Addacomment
|
YourAnswer
ThanksforcontributingananswertoStackOverflow!Pleasebesuretoanswerthequestion.Providedetailsandshareyourresearch!Butavoid…Askingforhelp,clarification,orrespondingtootheranswers.Makingstatementsbasedonopinion;backthemupwithreferencesorpersonalexperience.Tolearnmore,seeourtipsonwritinggreatanswers.
Draftsaved
Draftdiscarded
Signuporlogin
SignupusingGoogle
SignupusingFacebook
SignupusingEmailandPassword
Submit
Postasaguest
Name
Email
Required,butnevershown
PostYourAnswer
Discard
Byclicking“PostYourAnswer”,youagreetoourtermsofservice,privacypolicyandcookiepolicy
Nottheansweryou'relookingfor?Browseotherquestionstaggedpythonpropertiesdecoratorpython-decoratorspython-internalsoraskyourownquestion.
TheOverflowBlog
AIandnanotechnologyareworkingtogethertosolvereal-worldproblems
GettingthroughaSOC2auditwithyournervesintact
FeaturedonMeta
WhatgoesintositesponsorshipsonSE?
StackExchangeQ&AaccesswillnotberestrictedinRussia
NewUserExperience:DeepDiveintoourResearchontheStagingGround–How...
AskWizardforNewUsersFeatureTestisnowLive
Linked
2
RecursionError:maximumrecursiondepthexceededpythonpropertygettersetter
0
CallingaclassmemberfunctiongivesTypeError
-1
whatiswrongwiththispropertydecorator(python)
-3
Howcancallclassmethodwithoutbracket`()`?
1
Pythonpropertydetail
0
Whyisn'tthereanamingconflictindecoratingchainingcode?
1
Whydoesthepropertybuiltinworkinconjunctionwithclassesbutnotoutsideofthem?
-1
Whatdoesthepropertypythonbuiltindo?
0
Wheredoespython@setterreceiveitsargumentfromwhencalledfromwithinclass?
-3
Explaingetterandsetterinpythoninsimplewords
Seemorelinkedquestions
Related
3246
Howtocopyfiles?
11905
Whatdoesthe"yield"keyworddo?
5128
HowcanIsafelycreateanesteddirectory?
7201
DoesPythonhaveaternaryconditionaloperator?
3504
HowtogetthecurrenttimeinPython
3250
HowdoIconcatenatetwolistsinPython?
2468
HowtoupgradeallPythonpackageswithpip
3591
DoesPythonhaveastring'contains'substringmethod?
2865
HowtodeleteafileorfolderinPython?
HotNetworkQuestions
HowdoyouexplainCanada'sTrudeau'spower-sharingagreementtoafive-year-old(American)?
ConvertDateformattoinsertintoMySQLdatabase
InterpretationofasubtoureliminationconstraintintheTSP
HowDoesOrbitalWarfareWork?
EnigmarchDay1:Initial
Whatisagoodsoftwaretomaketechincaland/orschematicillustrationsaboutspace/orbitaldynamicstopics?
WhatcanweeatinthelateCretaceous?
TikZarcwithextremeangle
WhydoesahypersonicmissileneedtocruiseEarthatlowaltitudebeforehittingitsmark?
Whydoesn'ttheUSsendairplanestoUkraine,whenRussianssentMIGstoVietnamduringVietnamwar?
Iturnedabreakeroff,andnowthesecurityalarmsystemwon’tstopbeeping
problemswritingequation
IfplayerAisincheckbuthasamovewhichwillcheckmateplayerBwithoutexitingcheck,isthatmovelegal?
Howdoeslicensingsoftwarenotimplyownership?Don'tIownaWindowsoperatingsystemonceIpayforit?
NFA:Howdoesitfunctionwithempty-stringmoves?
Haskellcomparingtwolists'lengthsbutoneofthemisinfinite?
Howtoselectallcurvesonoroutsidearegion?
Creatingalistofconditions
WhydoAirForceplanesregularlyflyincircles?
Sandboxoverflow
WhatwouldUkrainegainbydisclosingintelligenceinformationaboutPutinassassinationplans?
WeirdpowerlinesforS-100,whyno5V?
Couldvideosbeauthenticatedusingprivateandpublickeys?
RecreateMinecraft'slighting
morehotquestions
Questionfeed
SubscribetoRSS
Questionfeed
TosubscribetothisRSSfeed,copyandpastethisURLintoyourRSSreader.
lang-py
Yourprivacy
Byclicking“Acceptallcookies”,youagreeStackExchangecanstorecookiesonyourdeviceanddiscloseinformationinaccordancewithourCookiePolicy.
Acceptallcookies
Customizesettings