I’m new to python and I would like some help. I created some classes with properties in order to keep me from passing meaningless arguments.
So for example I have this class
class match(object):
__teams=(None,None)
def setTeams(self,tms):
if type(tms) != type(list()) and type(tms) != type(tuple()):
raise Exception("Teams must be a list of length 2")
if len(tms) != 2:
raise Exception("Teams must be a list of length 2")
if (type(tms[0])==type(str()) or (type(tms[0])==type(unicode()))) \
and (type(tms[1])==type(str()) or type(tms[1])==type(unicode())):
self.__teams=tms
else:
raise Exception("Both teams must be strings")
return
teams=property(getTeams,setTeams)
If I write
match1=match()
match1.teams=(2,4)
I get an exception as I should, but
match1.teams[0]=5
does not raise an exception and passes the number 5. Please keep in mind that this is not all of the class, I just wrote down only what is relative to my question, so assume that the code behaves as I describe.
I guess this is because everything is passed by reference in python but I have to be careful not to assign meaningless data to my objects which defeats the purpose of having properties in the first place.
So, is there a way to fix that apart from not using lists or do I have to learn to live with it?
One of the advantages of
propertys is being able to do data validation — sometimes it is really important to make sure you get something very specific.In your case you need to do one of two things:
teamsdata in a structure that can’t be modified, such as atupleornamedtuple; then when the data is retrieved it cannot be changedor
getmethod return a copy of the data, so any modification do not mess up your originalThe first solution (immutable types) looks like this:
And when you try to assign after getting the value, this happens:
The second solution (returning a copy instead of the original) looks like this:
which has the following results:
As you can see, the changes did not make it back into the
matchobject.