Python: Is it possible to merge two __init__ after multiple inheritance? - python

I want my class Parents(Mom, Dad) to inheritance init attributes from two previous classes so then my input will require me to write mom_name and dad_name. Can someone suggest me how to do this?
class Mom(object):
def __init__(self, mom_name):
self.mom_name = mom_name
class Dad(object):
def __init__(self, dad_name):
self.dad_name = dad_name
class Parents(Mom, Dad):
pass
par = Parents('Mom', 'Dad')
print(par.mom_name)
print(par.dad_name)

you can implement it this way
class Mom(object):
def __init__(self, mom_name):
self.mom_name = mom_name
class Dad(object):
def __init__(self, dad_name):
self.dad_name = dad_name
class Parents(Mom, Dad):
def __init__(self, mom_name, dad_name):
Mom.__init__(self, mom_name)
Dad.__init__(self,dad_name)
par = Parents('Mom', 'Dad')
print(par.mom_name)
print(par.dad_name)
output
Mom
Dad

Like this.
class Parents(Mom, Dad):
def __init__(self, mom_name, dad_name):
super(Mom, self).__init__(mom_name)
super(Dad, self).__init__(dad_name)
Edit 1 :
The code above doesn't work, a suitable way will be to subclass Dad from Mum and then paste it to parents like this.
class Mom(object):
def __init__(self, mom_name):
self.mom_name = mom_name
class Dad(Mom):
def __init__(self, dad_name, **kw):
self.dad_name = dad_name
super(Dad, self).__init__(**kw)
class Parents(Dad):
def __init__(self, mom_name, dad_name):
super(Parents, self).__init__(mom_name=mom_name, dad_name=dad_name)
p = Parents("mumy", "dady")
print(p.mom_name)
print(p.dad_name)

Related

Using a variable from one class to another one in python

I want to use a variable from class A for some computation in class B. I,m not sure that I use the self.out from the class A in class B appropriately?
Class A:
class A(nn.Module):
def __init__(self):
super(A, self).__init__()
self.out = func()
Class B:
class B(nn.Module):
def __init__(self):
super(A, self).__init__()
self.result = function_1() + A.self.out
Maybe this is what you need. I made a small example of what I understood.
These "prints" were placed to improve the understanding that Class "C" can fetch any function or variable from the other parent classes.
class A():
def __init__(self):
variable = None
def test(self, number):
return f'another class {number}'
class B():
def __init__(self):
self.data = None
self.out = self.print_data(5)
def print_data(self, number):
return number
def print_elem(self):
return self.data
class C(A, B):
def __init__(self):
super().__init__()
c = C()
print(c.print_data(8))
print(c.out)
c.data = 100
print(c.print_elem())
print(c.test(3))

How to override a function in an inheritance hierarchy?

I would like to implement a widget system similar to FLTK using python in a 3D world.
I simplified my code to the following. I don't get the correct answer. The function is not overwritten even if I change the variable.
def callbacks():
print("callback")
def create():
print ("override")
def default():
print("default")
class f1(object):
def __init__(self):
self.test=default
pass
def docallback(self):
self.test()
class f2(f1):
def __init__(self):
self.test=create
super().__init__()
class f3(f2):
def __init__(self):
self.test=callbacks
super().__init__()
t1=f1()
t2=f2()
t3=f3()
t1.docallback()
t2.docallback()
t3.docallback()
You should be calling super().__init__() first in this case:
class f1(object):
def __init__(self):
self.test = default
def docallback(self):
self.test()
class f2(f1):
def __init__(self):
super().__init__()
self.test = create
class f3(f2):
def __init__(self):
super().__init__()
self.test = callbacks
These 'constructors' call super().__init__() first (which makes assignments to self.test), but then immediately assigns the correct value to self.test itself.
f1.__init__ should use default as the default value of a parameter, not a hard-coded assignment.
class f1:
def __init__(self, test=default):
self.test = test
Then f2 and f3 can simply provide different arguments when using super().
class f2:
def __init__(self):
super().__init__(create)
class f3:
def __init__(self):
super().__init__(callbacks)

How to subclass an Abstract Base Class?

Let's say I have an ABC:
class Template_ABC(metaclass=abc.ABCMeta):
def __init__(self, data=None, model=None):
self._data = data
self._model = model
#abc.abstractmethod
def do_stuff(self):
pass
#abc.abstractmethod
def do_more_stuff(self):
pass
I normally have a class of ABC, for example:
class Example_of_ABC(Template_ABC):
def do_stuff(self):
# Do stuff here
def do_more_stuff(self):
pass
Now, I want to subclass Example-of_ABC class. The only way I can do is as as follows:
class Subclass_of_Example_of_ABC(Example_of_ABC):
def __init__(self, data=None, model=None):
super().__init__(data, model)
def do_more_stuff(self):
# Do more stuff here
The issue with this way, is that I have to update my def _init__() for every subclass of the ABC. Is there anyway for the subclass to inherit all the inits from the ABC?

Python - Inheritance of a composition class

I have 2 classes that are a composition. And I would need to extend the functionality of both, so I would need to make use of inheritance from those base classes. Is it possible?
class Book:
def __init__(self):
self.sheets = generate_sheets()
author = ''
def generate_sheets(self):
for index in range(20):
(some_extra code)
self.sheets.append(Sheet(index))
class Sheet:
def __init__(self, idx):
self.id = idx
And I want to create 2 children of the base, and that the composition be between them. It would only possible overwriting the method generate_sheets?
class DefinitionBook(Book):
def __init__(self):
super().__init__()
translator = ''
def generate_sheets(self):
super().__init__()
for index in range(20):
self.sheets.append(DefSheet(index)
class DefSheet(Sheet):
def __init__
super().__init__()
definition = dict()
Or it would be possible to keep part of the code of the method generate_sheets in the child class of Book, and only change the part where is called to the class Sheet/DefSheet?
You could have the class Sheet (and subclasses) you need to use, as a class variable in the class Book (and subclasses); this voids the need to override generate_sheets in the subclasses.
class Sheet:
def __init__(self, idx):
self.id = idx
def __str__(self):
return f"{self.__class__.__name__}"
class Book:
sheet = Sheet
def __init__(self):
self.sheets = []
self.generate_sheets()
def generate_sheets(self):
for index in range(20):
self.sheets.append(self.__class__.sheet(index))
def __str__(self):
return f"{self.__class__.__name__} - {self.sheet.__name__}"
class DefSheet(Sheet):
def __init__(self, idx):
super().__init__(idx)
class DefinitionBook(Book):
sheet = DefSheet
def __init__(self):
super().__init__()
b = Book()
print(b, b.sheets[0])
d = DefinitionBook()
print(d, d.sheets[0])
output:
Book - Sheet Sheet
DefinitionBook - DefSheet DefSheet

Is it ok to have a property decorated method to return a class in Python?

Let's say I have the following code:
class MyClass(object):
def __init__(self, param):
self.param = param
#property
def super_param(self):
return Param(self, self.param)
class Param(object):
def __init__(self, parent, param):
self.param = param
self.parent = parent
#property
def get_parent(self):
return self.parent
My question is, is it considered bad practice to use the #property decorator in this way? Are there any pros or cons?
Why not just
class MyClass(object):
def __init__(self, param):
self.param = Param(self, param)
I don't think there's anything particularly wrong with returning a class from a property; a better question is, what are you trying to accomplish by doing so?
Edit: if you don't want it changed, make it a private property:
class MyClass(object):
def __init__(self, param):
self._param = param # naming convention, 'don't muck with it'
# OR
self.__param = param # name mangled
#property
def param(self):
return self._param

Categories

Resources