I have 3 classes, they inherit from parent class. A parameter in the init method of the child classes is used to define in parent to set a parameter an define how a method is called.
class Parent(object):
def __init__(self, marker):
self.executeCode(marker)
class ClassA(Parent):
def __init__(self, marker):
super(ClassA, self).__init__("class_a")
class ClassB(Parent):
def __init__(self, marker):
super(ClassB, self).__init__("class b")
class ClassC(Parent):
def __init__(self, marker):
super(ClassC, self).__init__("class c")
Which is the best pattern to use here, to make it more pythonic?
Related
I have this two classes that I needed to divide, though they share some common features. Is it possible to access first class' self.value from the second class? Please look at the pseudo code, surely more understandable then my words.
class a:
def __init__(self):
self.value = 45
class b(a):
def __init__(self):
self.other_value = #this should be self.value from class a
You need call the parent constructor first
class B(A):
def __init__(self):
super().__init__()
print(self.value)
you should call the parent constructor:
class b(a):
def __init__(self):
a.__init__(self)
#now you can use it with self.value
I have a parent class and several subclasses. Every subclass accepts different parameters, but all subclasses have some common parameters. I don't want to write the "common parameters" for every subclass. How can I do this?
class Parent:
def __init__(self, name):
self.name = name
class Subclass(Parent):
def __init__(self, age):
self.age = age
def do_something(self):
print(self.name)
instance = Subclass(name="Test", age=42)
instance.do_something() # 42
You can try this:
class Subclass(Parent):
def __init__(self, **kwargs):
super().__init__(kwargs['name'])
self.age = kwargs['age']
def do_something(self):
print(self.name)
And then use this just like you did in the question:
instance = Subclass(name="Test", age=42)
I use it in the following manner
You can add as many child classes as you want
class ParentClass(object):
def __init__(self,baseArgs):
self.var1=baseArgs['var1']
self.var2=baseArgs['var2']
self.var3=baseArgs['var3']
class ChildClass(ParentClass):
def __init__(self,childArgs,baseArgs):
super(ChildClass, self).__init__(baseArgs)
self.cvar1=childArgs['cvar1']
self.cvar2=childArgs['cvar2']
a=ChildClass({'cvar1':40,'cvar2':50},{'var1':10,'var2':20,'var3':30})
print(a.var1)
# 10
How can I make a common subclass initialize all parent classes it's inheriting from?
class Mom(object):
def __init__(self):
print("Mom")
class Dad(object):
def __init__(self):
print("Dad")
class Child(Mom, Dad):
def __init__(self):
super(Child, self).__init__()
c = Child() #only prints Mom
They are missing the super() calls in the Mom and Dad classes that are required for co-operative subclassing to work.
class Mom(object):
def __init__(self):
super(Mom, self).__init__()
print("Mom")
class Dad(object):
def __init__(self):
super(Dad, self).__init__()
print("Dad")
class Child(Dad, Mom):
def __init__(self):
super(Child, self).__init__()
c = Child() # Mom, Dad
You need to call super in Mom's __init__ as well.
I am trying to create a mixin class that has it's own properties, but as the class has no init to initialize the "hidden" variable behind the property.
class Software:
__metaclass__ = ABCMeta
#property
def volumes(self):
return self._volumes
#volumes.setter
def volumes(self, value):
pass
class Base(object):
def __init__(self):
self._volumes = None
class SoftwareUser(Base, Software):
def __init__(self):
super(Base, self).__init__()
So above is the best that I have come up with to solve this but the reality is that the _volumes dosn't really belong in the base. I could add an init to the Software class but then the super call wont work on both mixins.
The second is that I will need multiple mixins dependent on the incoming call they will always need the base, but the mixins will change so I dont really want variables from mixins that aren't mixed in for that call.
Is there a way that i can have the mixin add it's variables to the class if it is mixed in perhaps dynamically call the init of the mixin class ?.
Any questions let me know.
Thanks
Yes, that's wildly overcomplicated. A class (including mixins) should only be responsible for calling the next implementation in the MRO, not marshalling all of them. Try:
class Software:
#property
def volumes(self):
return self._volumes
#volumes.setter
def volumes(self, value):
pass
def __init__(self):
self._volumes = None
super().__init__() # mixin calls super too
class Base(object):
def __init__(self):
other_vars = None
class SoftwareUser(Software, Base): # note order
def __init__(self):
super().__init__() # all you need here
Ok so here is what I came up with, I am open to other answers, if I have made this way over complicated.
class Software:
#property
def volumes(self):
return self._volumes
#volumes.setter
def volumes(self, value):
pass
def __init__(self):
self._volumes = None
class Base(object):
def __init__(self):
other_vars = None
class SoftwareUser(Base, Software):
def _bases_init(self, *args, **kwargs):
for base in type(self).__bases__:
base.__init__(self, *args, **kwargs)
def __init__(self, *args, **kwargs):
self._bases_init(*args, **kwargs)
How do you call a method more than one class up the inheritance chain if it's been overridden by another class along the way?
class Grandfather(object):
def __init__(self):
pass
def do_thing(self):
# stuff
class Father(Grandfather):
def __init__(self):
super(Father, self).__init__()
def do_thing(self):
# stuff different than Grandfather stuff
class Son(Father):
def __init__(self):
super(Son, self).__init__()
def do_thing(self):
# how to be like Grandfather?
If you always want Grandfather#do_thing, regardless of whether Grandfather is Father's immediate superclass then you can explicitly invoke Grandfather#do_thing on the Son self object:
class Son(Father):
# ... snip ...
def do_thing(self):
Grandfather.do_thing(self)
On the other hand, if you want to invoke the do_thing method of Father's superclass, regardless of whether it is Grandfather you should use super (as in Thierry's answer):
class Son(Father):
# ... snip ...
def do_thing(self):
super(Father, self).do_thing()
You can do this using:
class Son(Father):
def __init__(self):
super(Son, self).__init__()
def do_thing(self):
super(Father, self).do_thing()