Python-Ref > Object oriented programming > Basics > Inheritance
 
 

<-^^->

Inheritance

Classes may be derived from other classes adding some functionality.
It is not always necessary to implement a class from scratch. Very often an already present object may be used and modified for our purposes. This ability is called inheritance and is one of the fundamental characteristics of OOP.
When creating a class derived from other class, we may override any of its methods, replacing them with our code. Methods that are not replaced will be taken from the original class. We may also call the parents methods of the same name by using "parent.method_name( self, ...)".
Expand/Shrink
Zdroj: (oop10-0.py)
  1   class Parent:
  2   
  3     def hello( self):
  4       print "Hello world"
  5   
  6   class Child( Parent):
  7   
  8     def goodbye( self):
  9       print "Goodbye"
 10   
 11   class GrandChild( Child):
 12   
 13     def hello( self):
 14       print "Hello from grandchild"
 15   
 16   p = Parent()
 17   c = Child()
 18   g = GrandChild()
 19   
 20   p.hello()
 21   
 22   c.hello()
 23   c.goodbye()
 24   
 25   g.hello()
 26   g.goodbye()
stdout:
Hello world
Hello world
Goodbye
Hello from grandchild
Goodbye
Doba běhu: 14.3 ms
The following example shows how we may create our own modification of the built-in file object that has the additional ability to log its actions onto the console.
Expand/Shrink
This is an example text in an example file.
It even has
several
lines.
Zdroj: (oop10-1.py)
  1   class LoggingFile( file):
  2     """file that also logs reads and writes to the console"""
  3   
  4     def __init__( self, filename, mode):
  5       file.__init__( self, filename, mode)
  6   
  7     def read( self):
  8       text = file.read( self)
  9       print "** reading %d bytes from %s" % (len( text), self.name)  # self.name was set by file
 10       return text
 11   
 12     def write( self, text):
 13       print "** writing %d bytes, %d lines to %s" % (len( text), text.count("\n")+1, self.name)
 14       file.write( self, text)
 15   
 16   
 17   f = LoggingFile( "example.txt", "r")
 18   print f.read()
 19   f.close()
 20   print
 21   
 22   f = LoggingFile( "whatever.txt", "w")
 23   f.write( "some text on \n 2 lines")
 24   f.close()
stdout:
** reading 71 bytes from example.txt
This is an example text in an example file.
It even has
several
lines.


** writing 22 bytes, 2 lines to whatever.txt
some text on 
 2 lines
Doba běhu: 21.7 ms
In the example above we did not override the "close" method and so the one from file was used. In the following code, we will provide our own "close" method.
Expand/Shrink
This is an example text in an example file.
It even has
several
lines.
Zdroj: (oop10-2.py)
  1   class LoggingFile( file):
  2     """file that also logs reads and writes to the console"""
  3   
  4     def __init__( self, filename, mode):
  5       file.__init__( self, filename, mode)
  6   
  7     def read( self):
  8       text = file.read( self)
  9       print "** reading %d bytes from %s" % (len( text), self.name)  # self.name was set by file
 10       return text
 11   
 12     def write( self, text):
 13       print "** writing %d bytes, %d lines to %s" % (len( text), text.count("\n")+1, self.name)
 14       file.write( self, text)
 15   
 16     def close( self):
 17       print "** closing file %s" % self.name
 18       file.close( self)
 19   
 20   
 21   f = LoggingFile( "example.txt", "r")
 22   print f.read()
 23   f.close()
 24   print
 25   
 26   f = LoggingFile( "whatever.txt", "w")
 27   f.write( "some text on \n 2 lines")
 28   f.close()
stdout:
** reading 71 bytes from example.txt
This is an example text in an example file.
It even has
several
lines.

** closing file example.txt

** writing 22 bytes, 2 lines to whatever.txt
** closing file whatever.txt
some text on 
 2 lines
Doba běhu: 21.4 ms
While it is possible to extend and modify the built-in classes using inheritance, more often we create both the parent and the derived classes ourselves. This permits us creation of hierarchy of objects and allows us to write the needed code only in one place.
Expand/Shrink
Prostředí:
.
|-- oop10-3.py
|-- something
|   `-- example.py
|-- something_else
`-- test
    `-- test.txt
Zdroj: (oop10-3.py)
  1   import os, shutil
  2   
  3   class FileSystemItem( object):
  4   
  5     def __init__( self, fullname):
  6       self.path, self.name = os.path.split( os.path.abspath( fullname))
  7   
  8     def get_full_name( self):
  9       return os.path.join( self.path, self.name)
 10   
 11     def copy( self, where):
 12       """this method is empty in the parent - children should implement it"""
 13       pass
 14   
 15   
 16   class File( FileSystemItem):
 17   
 18     def __init__( self, fullname):
 19       FileSystemItem.__init__( self, fullname)
 20   
 21     def copy( self, where):
 22       import shutil
 23       shutil.copy( self.get_full_name(), where)
 24   
 25     def get_size( self):
 26       return os.path.getsize( self.name)
 27   
 28     def __str__( self):
 29       return "File: %s" % self.get_full_name()
 30   
 31   
 32   class Directory( FileSystemItem):
 33   
 34     def copy( self, where):
 35       shutil.copytree( self.get_full_name(), where)
 36   
 37     def get_children( self):
 38       ret = []
 39       for name in os.listdir( self.get_full_name()):
 40         fullname = os.path.join( self.get_full_name(), name)
 41         if os.path.isfile( fullname):
 42           x = File( fullname)
 43           ret.append( x)
 44         elif os.path.isdir( fullname):
 45           x = Directory( fullname)
 46           ret.append( x)
 47       return ret
 48   
 49     def __str__( self):
 50       return "Directory: %s" % self.get_full_name()
 51   
 52   
 53   f = File( "oop10-3.py")
 54   print f
 55   print f.get_size()
 56   
 57   d = Directory( "something")
 58   print d
 59   print [str( ch) for ch in d.get_children()]
 60   d.copy( "new_dir")
stdout:
File: /mnt/bkchem.img/projects/python-ref/_tmp/oop10-3.py
1359
Directory: /mnt/bkchem.img/projects/python-ref/_tmp/something
['File: /mnt/bkchem.img/projects/python-ref/_tmp/something/example.py']
Prostředí:
.
|-- new_dir
|   `-- example.py
|-- oop10-3.py
|-- something
|   `-- example.py
|-- something_else
`-- test
    `-- test.txt
Doba běhu: 33.9 ms