.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/oop/inheritance.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note Click :ref:`here ` to download the full example code or to run this example in your browser via Binder .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_examples_oop_inheritance.py: ================= 3.13 inheritance ================= .. GENERATED FROM PYTHON SOURCE LINES 9-10 Inheritance means one class can inherit ``attributes`` and ``methods`` of parent class. .. GENERATED FROM PYTHON SOURCE LINES 12-30 .. code-block:: default class Human(object): def __init__(self, name): self.name = name def say_salam(self): print('Salam, my name is', self.name) class Muslim(Human): pass ali = Muslim('Ali') ali.say_salam() .. rst-class:: sphx-glr-script-out .. code-block:: none Salam, my name is Ali .. GENERATED FROM PYTHON SOURCE LINES 31-38 The ``Muslim`` class itself does not have a method ``say_salam`` but since it is inheriting from ``Human`` class and ``say_slam`` exists in ``Human`` class, we do end up calling ``say_salam`` method fo ``Human`` class. We can check the type of the ``ali`` which is an object and is an ``instance`` of class ``Muslim``. There are two ways to verify this. .. GENERATED FROM PYTHON SOURCE LINES 40-44 .. code-block:: default isinstance(ali, Muslim), type(ali) == Muslim .. rst-class:: sphx-glr-script-out .. code-block:: none (True, True) .. GENERATED FROM PYTHON SOURCE LINES 45-46 However, ``isinstance`` checks the parent classes as well but ``type`` function does not do so. .. GENERATED FROM PYTHON SOURCE LINES 48-51 .. code-block:: default isinstance(ali, Human), type(ali) == Human .. rst-class:: sphx-glr-script-out .. code-block:: none (True, False) .. GENERATED FROM PYTHON SOURCE LINES 52-57 .. code-block:: default arjun = Human('arjun') isinstance(arjun, Human), isinstance(arjun, Muslim) .. rst-class:: sphx-glr-script-out .. code-block:: none (True, False) .. GENERATED FROM PYTHON SOURCE LINES 58-62 So it is always safe to check the type of an object by ``instance``. Inheritance can occur between more than two classes as well. In following, ``Pakistani`` class inherits from `Muslim` class which itself inherits from ``Human`` class. .. GENERATED FROM PYTHON SOURCE LINES 64-84 .. code-block:: default class Human(object): def __init__(self, name): self.name = name class Muslim(Human): pass class Pakistani(Muslim): pass ali = Pakistani('ali') isinstance(ali, Human) .. rst-class:: sphx-glr-script-out .. code-block:: none True .. GENERATED FROM PYTHON SOURCE LINES 85-87 We can override the methods of parent or super class in its child class by simply redefining the ``method``. .. GENERATED FROM PYTHON SOURCE LINES 89-110 .. code-block:: default class Human(object): def __init__(self, name): self.name = name def introduction(self): print('Hello, my name is', self.name) class Muslim(Human): def introduction(self): print('Salam, my name is', self.name) ali = Muslim("ali") ali.introduction() .. rst-class:: sphx-glr-script-out .. code-block:: none Salam, my name is ali .. GENERATED FROM PYTHON SOURCE LINES 111-114 .. code-block:: default Human.introduction(ali) .. rst-class:: sphx-glr-script-out .. code-block:: none Hello, my name is ali .. GENERATED FROM PYTHON SOURCE LINES 115-117 If in a child class we want to call/use method from a parent/super class, we can call method from parent/super class using the `super()` function as following. .. GENERATED FROM PYTHON SOURCE LINES 119-141 .. code-block:: default class Human(object): def __init__(self, name): self.name = name def introduction(self): print('Hello, my name is', self.name) class Muslim(Human): def introduction(self): print("I will call introduction method of parent class") super().introduction() ali = Muslim("ali") ali.introduction() .. rst-class:: sphx-glr-script-out .. code-block:: none I will call introduction method of parent class Hello, my name is ali .. GENERATED FROM PYTHON SOURCE LINES 142-143 Above, the ``introduction`` method of ``Muslim`` class calls the ``introduction`` method of ``Human``. .. GENERATED FROM PYTHON SOURCE LINES 145-173 .. code-block:: default class Human(object): def __init__(self, name): self.name = name def introduction(self): print('Hello, my name is', self.name) class Muslim(Human): def introduction(self): print("salam: my name is ", self.name) class Pakistani(Muslim): def introduction(self): print("I will call introduction method of parent class") super().introduction() ali = Pakistani("ali") ali.introduction() .. rst-class:: sphx-glr-script-out .. code-block:: none I will call introduction method of parent class salam: my name is ali .. GENERATED FROM PYTHON SOURCE LINES 174-177 If a method is not present in super / parent class , python will keep on looking in all parent / super classes in the hierarchy until it finds the method or attribute being called. .. GENERATED FROM PYTHON SOURCE LINES 179-206 .. code-block:: default class Human(object): def __init__(self, name): self.name = name def introduction(self): print('Hello, my name is', self.name) class Muslim(Human): pass class Pakistani(Muslim): def introduction(self): print("I will call introduction method of parent class") super().introduction() ali = Pakistani("ali") ali.introduction() .. rst-class:: sphx-glr-script-out .. code-block:: none I will call introduction method of parent class Hello, my name is ali .. GENERATED FROM PYTHON SOURCE LINES 207-229 .. code-block:: default class Human(object): def __init__(self, name): self.name = name def introduction(self): print('Hello, my name is', self.name) class Muslim(Human): pass class Pakistani(Muslim): pass ali = Pakistani("ali") ali.introduction() .. rst-class:: sphx-glr-script-out .. code-block:: none Hello, my name is ali .. GENERATED FROM PYTHON SOURCE LINES 230-232 However, if the called method does not exist in any of the parent classes, then python will throw ``AttributeError``. .. GENERATED FROM PYTHON SOURCE LINES 234-258 .. code-block:: default class Human(object): def __init__(self, name): self.name = name def introduction1(self): print('Hello, my name is', self.name) class Muslim(Human): pass class Pakistani(Muslim): pass ali = Pakistani("ali") # uncomment following line # ali.introduction() # AttributeError .. GENERATED FROM PYTHON SOURCE LINES 259-265 If in a child class , we want to implement a method of a parent class but not of immediate parent class, we can directly call that method. Below, ``Pakistani`` class is inheriting from ``Muslim`` but in introduction method of ``Pakistani``, we don’t want to call ``introduction`` method of ``Muslim`` class rather we want to call ``introduction`` method of ``Human`` class.We can do this by ``Human.introduction()`` .. GENERATED FROM PYTHON SOURCE LINES 267-295 .. code-block:: default class Human(object): def __init__(self, name): self.name = name def introduction(self): print('Hello, my name is', self.name) class Muslim(Human): def introduction(self): print('Salam, my name is', self.name) class Pakistani(Muslim): def introduction(self): Human.introduction(self) print("I am a Pakistani. ") ali = Pakistani("ali") ali.introduction() .. rst-class:: sphx-glr-script-out .. code-block:: none Hello, my name is ali I am a Pakistani. .. GENERATED FROM PYTHON SOURCE LINES 296-297 One of the function of method overriding is to implement abstract methods. .. GENERATED FROM PYTHON SOURCE LINES 299-325 .. code-block:: default class Human(object): def nationality(self): raise NotImplementedError("implement this method in child class") class Pakistani(Human): def nationality(self): return "pakistani" class Iranian(Human): def nationality(self): return "iranian" class Israili(Human): pass ali = Pakistani() ali.nationality() .. rst-class:: sphx-glr-script-out .. code-block:: none 'pakistani' .. GENERATED FROM PYTHON SOURCE LINES 326-330 .. code-block:: default armaghan = Iranian() armaghan.nationality() .. rst-class:: sphx-glr-script-out .. code-block:: none 'iranian' .. GENERATED FROM PYTHON SOURCE LINES 331-337 .. code-block:: default yakov = Israili() # uncomment following line # yakov.nationality() # NotImplementedError .. GENERATED FROM PYTHON SOURCE LINES 338-339 We can enlist all base classes in a hierarchy of given class. .. GENERATED FROM PYTHON SOURCE LINES 339-358 .. code-block:: default class Human(object): pass class Muslim(Human): pass class Pakistani(Human): pass class Punjabi(Pakistani): pass print(Punjabi.__mro__) .. rst-class:: sphx-glr-script-out .. code-block:: none (, , , ) .. GENERATED FROM PYTHON SOURCE LINES 359-362 .. code-block:: default print(Muslim.__mro__) .. rst-class:: sphx-glr-script-out .. code-block:: none (, , ) .. GENERATED FROM PYTHON SOURCE LINES 363-365 We can initiate a child class with additional arguments than required to initiate the parent class. For this we have to overwrite ``__init__()`` method of the child class. .. GENERATED FROM PYTHON SOURCE LINES 367-391 .. code-block:: default class Human(object): def __init__(self, name): self.name = name def introduction(self): print('Hello, my name is', self.name) class Muslim(Human): def __init__(self, name, sect): self.sect = sect super(Muslim, self).__init__(name) def introduction(self): print('Salam, my name is {} and my sect is {}'.format(self.name, self.sect)) # Uncomment following line # ali = Muslim("ali") # TypeError .. GENERATED FROM PYTHON SOURCE LINES 392-394 Above, the ``Muslim`` class now requires two arguments for initiation i.e. `name`` and `sect`. We did not provide value for ``sect``. .. GENERATED FROM PYTHON SOURCE LINES 396-401 .. code-block:: default ali = Muslim("ali", None) ali.introduction() .. rst-class:: sphx-glr-script-out .. code-block:: none Salam, my name is ali and my sect is None .. GENERATED FROM PYTHON SOURCE LINES 402-403 Instead of using ``super(ChildClass, self).__init__()`` we can also simple say ``super().__init__()``. .. GENERATED FROM PYTHON SOURCE LINES 406-429 .. code-block:: default class Human(object): def __init__(self, name): self.name = name def introduction(self): print('Hello, my name is', self.name) class Muslim(Human): def __init__(self, name, sect): self.sect = sect super().__init__(name) def introduction(self): print('Salam, my name is {} and my sect is {}'.format(self.name, self.sect)) ali = Muslim("ali", None) ali.introduction() .. rst-class:: sphx-glr-script-out .. code-block:: none Salam, my name is ali and my sect is None .. GENERATED FROM PYTHON SOURCE LINES 430-433 .. code-block:: default type(ali.sect) .. GENERATED FROM PYTHON SOURCE LINES 434-440 .. code-block:: default kapil = Human('kapil') # uncomment following line # kapil.sect # AttributeError .. GENERATED FROM PYTHON SOURCE LINES 441-443 Since ``kapil`` is an instance of ``Human`` class which does not have any attribute named ``sect``, thus we could not access this attribute. .. GENERATED FROM PYTHON SOURCE LINES 445-448 multiple-inheritance --------------------- A class can also inherit from multiple classes and this is called ``multiple-inheritance``. .. GENERATED FROM PYTHON SOURCE LINES 450-469 .. code-block:: default class Spirit(object): chastity = 'NaN' bravery = 'NaN' tolerance = 'NaN' class Body(object): weight = 20 class Human(Spirit, Body): pass ali = Human() print(ali.chastity) .. rst-class:: sphx-glr-script-out .. code-block:: none NaN .. GENERATED FROM PYTHON SOURCE LINES 470-473 .. code-block:: default print(ali.weight) .. rst-class:: sphx-glr-script-out .. code-block:: none 20 .. GENERATED FROM PYTHON SOURCE LINES 474-476 If an attribute of the child class is called, it is first looked in the child class, then in the first parent class and then in second parent class. .. GENERATED FROM PYTHON SOURCE LINES 478-497 .. code-block:: default class Spirit(object): chastity = 'NaN' bravery = 'NaN' identity = 'NaN' class Body(object): identity = 'name' class Human(Spirit, Body): pass ali = Human() print(ali.identity) .. rst-class:: sphx-glr-script-out .. code-block:: none NaN .. GENERATED FROM PYTHON SOURCE LINES 498-504 Above, ``identity`` attribute exists for ``Body`` and ``Spirit`` class but since ``Spirit`` class comes first, so ``NaN`` is printed which is value of ``identity`` attribute of ``Spirit`` class. Sometimes, we may want to initialize both parent classes with separate initializing arguments. In following, ``Body`` class requires two initiating arguments while ``Spirit`` class can be initialized with as many arguments as possible. .. GENERATED FROM PYTHON SOURCE LINES 506-540 .. code-block:: default class Spirit(object): def __init__(self, **kwargs): print("initializing spirit") for k, v in kwargs.items(): print('setting: ', k, 'to ', v) setattr(self, k, v) print("finished initializing spirit") class Body(object): def __init__(self, weight, height): print("initializing body") self.weight = weight self.height = height print("finished initializing body") class Human(Spirit, Body): def __init__(self, name, weight, height, **kwargs): print("initializing Human") self.name = name Spirit.__init__(self, **kwargs) Body.__init__(self, weight, height) ali = Human('ali', 60, 175, chastity='NotANumber') print("Name: ", ali.name) print("Weight: ", ali.weight) print("Height: ", ali.height) print("Chastity: ", ali.chastity) .. rst-class:: sphx-glr-script-out .. code-block:: none initializing Human initializing spirit setting: chastity to NotANumber finished initializing spirit initializing body finished initializing body Name: ali Weight: 60 Height: 175 Chastity: NotANumber .. GENERATED FROM PYTHON SOURCE LINES 541-543 Instead of initializing both parent classes separately, call to ``super()`` method will suffice to initiate all parent classes at once. .. GENERATED FROM PYTHON SOURCE LINES 546-577 .. code-block:: default class Spirit(object): def __init__(self, **kwargs): print("initializing spirit") for k, v in kwargs.items(): print('setting: ', k, 'to ', v) setattr(self, k, v) print("finished initializing spirit") class Body(object): def __init__(self, weight, height): print("initializing body") self.weight = weight self.height = height print("finished initializing body") class Human(Spirit, Body): def __init__(self, name, weight, height, **kwargs): print("initializing Human") self.name = name super().__init__(weight=weight, height=height, **kwargs) ali = Human('ali', 60, 175, chastity='NotANumber', honesty="undefined") print("Name: ", ali.name) print("Weight: ", ali.weight) print("Height: ", ali.height) print("Chastity: ", ali.chastity) .. rst-class:: sphx-glr-script-out .. code-block:: none initializing Human initializing spirit setting: weight to 60 setting: height to 175 setting: chastity to NotANumber setting: honesty to undefined finished initializing spirit Name: ali Weight: 60 Height: 175 Chastity: NotANumber .. rst-class:: sphx-glr-timing **Total running time of the script:** ( 0 minutes 0.015 seconds) .. _sphx_glr_download_auto_examples_oop_inheritance.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: binder-badge .. image:: images/binder_badge_logo.svg :target: https://mybinder.org/v2/gh/AtrCheema/python-seekho/master?urlpath=lab/tree/notebooks/auto_examples/oop/inheritance.ipynb :alt: Launch binder :width: 150 px .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: inheritance.py ` .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: inheritance.ipynb ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_