Computer Science Canada

[Python-tut] Private Instance Variables

Author:  wtd [ Tue Nov 08, 2005 3:54 pm ]
Post subject:  [Python-tut] Private Instance Variables

So you've created an object in Python:

Python:
class StudentRecord(object):
   def __init__(self, name, grades = []):
      self.name = name
      self.grades = grades
   def add_grade(self, new_grade):
      self.grades.append(new_grade)
   def max_grade(self):
      return max(self.grades)
   def min_grade(self):
      return min(self.grades)
   def avg_grade(self):
      return float(sum(self.grades)) / len(self.grades)


And you create an instance:

Python:
bob = StudentRecord("Bob", [100, 76, 89, 34])


Now, it's pretty obvious that if you call:

Python:
bob.max_grade()


You should get 100. But what if I was an idiot and wrote:

Python:
bob.grades = []


What will Python do to stop me?

Python won't do a darn thing, because the grades list was public.

So, the question is how we go about making it private.

Python:
class StudentRecord(object):
   def __init__(self, name, grades = []):
      self.name = name
      self.__grades = grades
   def add_grade(self, new_grade):
      self.__grades.append(new_grade)
   def max_grade(self):
      return max(self.__grades)
   def min_grade(self):
      return min(self.__grades)
   def avg_grade(self):
      return float(sum(self.__grades)) / len(self.__grades)


That's great, but now how do I get to that list in a read-only fashion?

Python:
class StudentRecord(object):
   def __init__(self, name, grades = []):
      self.name = name
      self.__grades = grades
   def add_grade(self, new_grade):
      self.__grades.append(new_grade)
   def max_grade(self):
      return max(self.__grades)
   def min_grade(self):
      return min(self.__grades)
   def avg_grade(self):
      return float(sum(self.__grades)) / len(self.__grades)
   def __get_grades(self):
      return self.__grades
   grades = property(__get_grades)


Or alternatively:

Python:
class StudentRecord(object):
   def __init__(self, name, grades = []):
      self.name = name
      self.__grades = grades
   def add_grade(self, new_grade):
      self.__grades.append(new_grade)
   def max_grade(self):
      return max(self.__grades)
   def min_grade(self):
      return min(self.__grades)
   def avg_grade(self):
      return float(sum(self.__grades)) / len(self.__grades)
   grades = property(lambda self: self.__grades)


The property function can also be used to create "setters" as well as "getters".

Author:  Mazer [ Tue Nov 08, 2005 4:48 pm ]
Post subject: 

This is great! I was hoping that something like this existed.

Author:  [Gandalf] [ Tue Nov 08, 2005 4:53 pm ]
Post subject: 

Something I can learn Smile. I'll go through it once I learn a bit more of the basics...


: