Inheritance of class in Python? - python

Suppose I have a parent class A and a daughter class B. Now A has 10 methods in it and B requires only three of those methods. How can this be done?

There is nothing special to do.
Just inherit class A:
class B(A):
super(B, self).__init__():
Use/override the methods you need and ignore the rest.

Related

difference between multiple inheritance and multilevel inheritance

one non mature question on inheritance :-)
Say I have classes
class A (B)
{code}
class B(C)
{code}
class C(object)
def function1()
{code}
I can access function1() with following code
obj=A()
obj.function1()
Since we have multilevel inheritance, we can get it.
I believe I can do the same using multiple inheritance ? like
class A(B,C) ?
What is the difference here?
Where can i get true use case of multilevel inheritance over multiple inheritance?
class Base1:
pass
class Base2:
pass
class MultiDerived(Base1, Base2):
pass
this is an example of multiple inheritance . In that a single class can inherit multiple classes .
In multilevel if you have a class
class A
{code}
class B (A)
{code}
class C (B)
{code}
in this you Inherit class A property in class C when you Inherited class b . so if a class has inherited some class and you dont want to inherit property of superclass than multiple inheritance is used .
for more info with diagram refer to this link :- https://www.programiz.com/python-programming/multiple-inheritance
In your particular example both definitions of class A will have the same effect. But if you add function1 to class B as well, then you can decide which version of function1 will be called from class A, by adjusting multiple inheritance order when defining class A.
So you can do this like this:
class A(B,C)
or like that:
class A(C,B)
Problem with multiple inheritance is function overloading. Imagine this:
class A:
def test(self):
print("class A")
class B:
def test(self):
print("class B")
class C(A, B):
pass
c = C()
c.test()
Can you guess what the output will be? (it's class A). In case of multilevel inheritance you have more control over overriding methods. It's less likely for you to make mistake using multilevel inheritance. You can simple overlook that your parent classes are implementing same method for your child class.
But to be honest, as long as you know how to handle multiple inheritance in python and you know the problems with it - you should be fine using either. Check official python documentantion for the multiple inheritance.

Multilevel abstraction with interface and inheritance in Python

I'm not exactly sure how to phrase this question, hence the strange title. I also have not been able to find any information on this after searching, so hopefully this isn't a duplicate and I'm just searching for the wrong words. Anyhow, here is the situation, I have an abstract base class with some methods in it, which is inherited by a class. I don't want to set one of the methods in this base class, as this class is meant to be inherited by other classes to provide the common functionality they all share. Something like:
class A(metaclass=abc.ABCMeta):
#abc.abstractmethod
def fun1(self):
pass
#abc.abstractmethod
def fun2(self):
pass
class B(A):
def fun1(self):
#do work here
#abc.abstractmethod
def fun2(self): # Intent to have the final classes define this
pass
class C(B):
def fun2(self):
# do work here
class D(B):
def fun2(self):
# do work here
I would like to keep the function as an ABC.meta to force implementation on the final children, but because there can be multiple types of class B in this case all inheriting from the interface, I want to keep the initial virtulization of the method at this root class, but have a way for class B to enforce that it's sub-classes must implement this. The code works just find if I don't add the abstract method to class B, but that is awkward since subclassess must implement the method and shouldn't have to look all the way up to the interface to figure out everything they need to implement. As written, it will error out because class B cannot declare the method as an abc.abstract. If I don't declare it as an abstract there is no way to enforce the child class has to implement the method.
I hope my convoluted way of writing this makes sense to someone out there...
Thanks!
You probably should not redefine fun2 as an abstract method in the concrete class B. You are creating a set of rules for your interface, but immediately violating them when you do that.
Instead, either define a mix-in class or an additional ABC that C and D can inherit.
class A(metaclass=abc.ABCMeta):
#abc.abstractmethod
def fun1(self):
pass
class A2(metaclass=abc.ABCMeta):
#abc.abstractmethod
def fun2(self):
pass
class B(A):
def fun1(self):
print('hello')
class B2(A2):
def fun2(self):
print('world')
class C(B, B2):
pass
class D(B, B2):
pass

How to create abstract classes using abc without using an abstract method?

Using abc, I can create abstract classes using the following:
from abc import ABC, abstractmethod
class A(ABC):
#abstractmethod
def foo(self):
print('foo')
class B(A):
pass
obj = B()
This will fail because B has not defined the method foo.
This mimics the abstract method functionality in Java.
I wanted to know if the abstract class functionality is also present in Python, where instantiation of a class is prevented without having any abstract methods.
The conventional way to create an abstract class in Python is to raise the built-in exception NotImplementedError.
class A(object):
def __init__(self):
raise NotImplementedError('abstract base class')
class B(A):
def __init__(self):
# don't call A.__init__ here.
pass
b = B()
# a = A() # This will fail.
Yes. You can.
If you want to not enforce method implementation:
Simply inherit from ABC but don't delcare a method abstract, so it needn't be implemented in its subclasses.
If you want the abstract class to enforce the implementation of all methods:
Decorate all methods.
If you want to enforce the implementation of a method that does not belong to an ABC:
Raise NotImplementedErrorin the method. This won't prevent instantiation, but usage. However, if you want to prevent it in the instantiation, you should rather use ABC's.
You can also delcare __init__ an abstractmethod, but generally this does not look very useful to me.

How to refer from child class to child class of another class

I know the title of the question is very confusing. I couldn't come up with anything meaningful. Let me explain it.
I have two classes, let's call them A and B:
class A(object):
def get_instance_of_b():
return B()
class B(object):
pass
In it I have a method that refers to instance of class B.
I have 4 classes that inherit from A and another 4 classes that inherit from class B. Now what I want is to avoid rewriting get_instance_of_b() method. Class A1 (child of A) should get an instance of B1 (child of B) and so on.
What is the best way to do it? Or maybe I'm going wrong with classes structure?
To give a context to what my classes do: class A processes data and class B validates input parameters. All children of class A share some general parameters but children classes also have their own specific parameters.
You should have an explicit mapping of your A classes (your "processors") to your B classes (your "validators"), and do the lookup that way.
class A(object):
def get_validator(self):
return validators[self.__class__]()
class A1(A):
...
class B(object):
...
class B1(B):
...
validators = {A:B, A1:B1}
And use as such:
>>> a1 = A1()
>>> a1.get_validator()
<__main__.B1 object at ...>

Abstract method inheritance in Python

Let's assume that we have a Python class that makes use of the abc module to define an abstract attribute:
import abc
class A(object):
__metaclass__ = abc.ABCMeta
#abc.abstractproperty
def test_attribute(self):
raise NotImplementedError
Let's now consider to define B that subclasses from A by adding a new method (test_method()), and C that subclasses from B implementing the abstract method originally declared in A:
class B(A):
def test_method(self):
pass
class C(B):
def test_attribute(self):
# Implement abstract attribute
pass
Assuming that I would like to keep B abstract (non-instantiable), shall I redefine the abstract property (test_attribute) and the metaclass assignment also in B? Or is it enough to inherit them from A (as in the above code)?
I know that Python allows me to not redefine the abstract methods and thus inherit them from the parent class. Is this correct from a theoretical software engineering perspective?
I'm asking so because if I'm not wrong other languages (such as Java) do not allow inheritance of abstract methods without reimplementing them as abstract...
You've pretty much got all the code there, you can always test it and see if it works ... but as a spoiler, Your design is fine so long as C.test_attribute gets decorated with property.
If you try to make an instance of B, then you'll have problems since the whole abstract interface hasn't been created, but it is fine to create it as a base class for C (and presumably other classes later...)
e.g.:
import abc
class A(object):
__metaclass__ = abc.ABCMeta
#abc.abstractproperty
def foo(self):
pass
class B(A):
def bar(self):
return "bar"
class C(B):
#property
def foo(self):
return "foo"
print C().foo # foo
print C().bar() # bar
print B().foo # TypeError

Categories

Resources