Hi,
I have a code that creates a class 'Person' :

class Person:
    def __init__(self, fname, lname):
        self._fname = fname
        self._lname = lname

    def fname(self):
        return self._fname

    def set_fname(self, fname):
        self._fname = fname

    def lname(self):
        return self._lname

    def set_lname(self, lname):
        self._lname = lname

    def name(self):
        return self._fname + ' ' + self._lname

What I dont get is what these code blocks do:

def set_fname(self, fname):
        self._fname = fname

 def set_lname(self, lname):
        self._lname = lname

What exactly does the set_fname and set_lname do? and how come the self._fname and self._lname are inaccessible?

Thanks in advance,
ymf

What I dont get is what these code blocks do:

def set_fname(self, fname):
        self._fname = fname

 def set_lname(self, lname):
        self._lname = lname

What exactly does the set_fname and set_lname do? and how come the self._fname and self._lname are inaccessible?

Those blocks of code reassign the value of _lname and _fname. self._fname and self._lname are not technically inaccessible, they are just simply hidden to the common user. If you typ

>>> p1 = Person('James', 'Matthews')
>>> p1
<__main__.Person instance at 0x01C84FD0>
>>> p1.fname()
'James'
>>> p1._fname
'James'
>>>

As you can see, I can still access those objects. However the helper function fname() makes it easier on the user.

Just to jlm's good points above, the getter and setter functions allow the object to control access to its own data members.

For instance, suppose you have a sprite that can rotate. Clearly, if the rotation is greater than 360 degrees, then you want to reduce the rotation to its reference angle between 0 and 360. So you would write:

def set_angle(self, angle):
   self._angle = angle % 360

Now, set_angle controls access to self._angle so that it always has a valid value.

Hence, the data member self._angle is private and is only ever accessed by the object itself. That guarantees that some outside client can't dork up _angle by setting it to an illegal value.

But the method to set it, set_angle, is public.

This is VERY important concept in object-oriented programming: data members should be private; methods should be public (there are exceptions, but that's the good rule-of-thumb).

One more thing: having defined your getter and setter functions, you can now create a public data member that looks like a regular data member, but restricts access as described above. Here's how:

def get_angle(self):
    return self._angle

def set_angle(self, angle):
   self._angle = angle % 360

angle = property(get_angle, set_angle)

Now, you can make statements like this:

self.angle = 450

and the setter function will be automagically called just as if you had written

self.set_angle(450)

So the real prize in writing getter and setter functions is that you can protect your object from illegal values; from there, public properties allow you to set values without the awkward method calls.

Hope that helps,
Jeff

This article has been dead for over six months. Start a new discussion instead.