Python-Ref > Object oriented programming > Basics > Private methods and attributes
 
 

<-^^->
Klíčová slova
Moduly
Knihovní funkce

Private methods and attributes

How to create methods and attributes accessible only by the class itself.
Sometimes methods provide useful building blocks for the functionality of a class but should not be used from outside of it (there can for instance be a special routine to clean up data after such methods or they can have some harmful side effects when used without the knowledge of internal workings of the class). In such cases it might be useful to make such methods or attributes private.
While such privacy can be accomplished (to some degree) in Python, it is always enough just to remind the user that some members are intended for private use only. This is by custom done by prepending the name of the member with one underscore ("_") - see program 2 here.
If even suggestion to the user is not enough, two underscores may be used which will cause the member to be "invisible" from the outside (we will see in a momemt that this is not in fact completly true when we describe the mechanism how this feature works).
Expand/Shrink
Zdroj: (oop7-1.py)
  1   class Rectangle:
  2   
  3     def __init__( self, color):
  4       self.setColor( color)
  5   
  6     def setColor( self, color):
  7       self._color = color
  8       self.draw()
  9   
 10     def getColor( self):
 11       return self._color
 12   
 13     def draw( self):
 14       print "Redrawing to color", self.getColor()
 15   
 16   rec = Rectangle( "blue")
 17   rec._color = "red"  # here we access the attribute without using
 18                       #proper method and force the object out of sync
 19   print rec.getColor()
stdout:
Redrawing to color blue
red
Doba běhu: 22.3 ms
Expand/Shrink
Zdroj: (oop7-2.py)
  1   class Rectangle:
  2   
  3     def __init__( self, color):
  4       self.setColor( color)
  5   
  6     def setColor( self, color):
  7       self.__color = color
  8       self.draw()
  9   
 10     def getColor( self):
 11       return self.__color
 12   
 13     def draw( self):
 14       print "Redrawing to color", self.getColor()
 15   
 16   rec = Rectangle( "blue")
 17   print rec.getColor()
 18   print rec.__color   # the attribute is not visible from outside the class
stdout:
Redrawing to color blue
blue
stderr:
Traceback (most recent call last):
  File "oop7-2.py", line 18, in ?
    print rec.__color   # the attribute is not visible from outside the class
AttributeError: Rectangle instance has no attribute '__color'
Doba běhu: 20.8 ms
Expand/Shrink
Zdroj: (oop7-3.py)
  1   class Rectangle:
  2   
  3     def __init__( self, color):
  4       self.setColor( color)
  5   
  6     def setColor( self, color):
  7       self.__color = color
  8       self.draw()
  9   
 10     def getColor( self):
 11       return self.__color
 12   
 13     def draw( self):
 14       print "Redrawing to color", self.getColor()
 15   
 16   rec = Rectangle( "blue")
 17   rec.__color = "red"  # here we create a new attribute without touching the private one
 18   print rec.getColor()
 19   print rec.__color
stdout:
Redrawing to color blue
blue
red
Doba běhu: 20.7 ms
The hiding of attributes and methods with names starting with two undesrcores is not complete. It is more what is called a security through obscurity - it protects the memeber by mangling its name so that it visible from the ouside under different name. Thus the users who knows what is going on is free to shoot himself into the foot, but he has to take extra effort.
In the following example we demonstrate the way in which the name mangling is done - the name of a member is internally prepended by an underscore and the name of the class it belongs to.
Expand/Shrink
Zdroj: (oop7-4.py)
  1   class Rectangle:
  2   
  3     def __init__( self, color):
  4       self.setColor( color)
  5   
  6     def setColor( self, color):
  7       self.__color = color  # appears as _Rectangle__color from the outside
  8       self.draw()
  9   
 10     def getColor( self):
 11       return self.__color
 12   
 13     def draw( self):
 14       print "Redrawing to color", self.getColor()
 15   
 16   rec = Rectangle( "blue")
 17   print rec.getColor()
 18   print rec._Rectangle__color
stdout:
Redrawing to color blue
blue
blue
Doba běhu: 21.0 ms