Overriding in Python - python

I want to be able to do the following
class Parent:
def __init__(self):
pass
def Create(self):
return 'Password'
class Child(Parent):
def __init__(self):
self.Create()
def Create(self):
return 'The '+self.Create #I want to return 'The Password'
I would like to get a parent function from a child class in a function that is overriding it. I am not sure how to do this.
This is a little hard to explain, comment if you are having trouble understanding.
Edit:
Thanks for the answers everyone, I almost thought that this was impossible.

The super() function is meant for cases like this. However, it only works on "new-style" classes, so you'll need to modify your definition of Parent to inherit from object as well (you should always be using "new-style" classes, anyway).
class Parent(object):
def __init__(self):
pass
def Create(self):
return 'Password'
class Child(Parent):
def __init__(self):
self.Create()
def Create(self):
return 'The ' + super(Child, self).Create()
print Child().Create() # prints "The Password"

Either refer to the parent explicitly or (in new-style classes) use super().
class Child(Parent):
...
def Create(self):
return 'The ' + Parent.Create(self)

Its as simple as referring to the base class via super:
class Child(Parent):
def __init__(self):
self.Create()
def Create(self):
return 'The '+ super(Child, self).Create()

Use the super function to access the parent super(Child,self).create() to call create from the parent.

You can use "super()" to call the super class method "Create()" as shown below:
class Parent:
def __init__(self):
pass
def Create(self):
return 'Password'
class Child(Parent):
def __init__(self):
self.Create()
def Create(self): # Here
return 'The ' + super().Create()
print(Child().Create()) # The Password

Related

Execute parent class method in child class argument values python

Hi I have a simple Inheritance example in Python.
class Person:
def __init__(self,name):
self.name=name
self.name0=name[0]
self.name1=name[1]
self.lastchar=self.returnSomechar()
def returnfirstchar(self):
return self.name[0]
def returnSomechar(self):
self.p=self.name1
return self.p
class Employee(Person):
def returnfirstchar(self):
""" I dont implement at all"""
def returnSomechar(self):
a='Lawson'
b='Jack'
self.p=self.name1+a+b
#
return super(Employee,self).returnSomechar()
e=Employee('David')
e.returnSomechar()
This returned 'a'
I expected the child class self.p to get passed and result would be David Lawson Jack
Cleary In child class super() didnt use the self.p of child class rather it used self.p of base class.
can you please help where i am missing
Thanks

I want to call parent class method which is overridden in child class through child class object in Python

class abc():
def xyz(self):
print("Class abc")
class foo(abc):
def xyz(self):
print("class foo")
x = foo()
I want to call xyz() of the parent class, something like;
x.super().xyz()
With single inheritance like this it's easiest in my opinion to call the method through the class, and pass self explicitly:
abc.xyz(x)
Using super to be more generic this would become (though I cannot think of a good use case):
super(type(x), x).xyz()
Which returns a super object that can be thought of as the parent class but with the child as self.
If you want something exactly like your syntax, just provide a super method for your class (your abc class, so everyone inheriting will have it):
def super(self):
return super(type(self), self)
and now x.super().xyz() will work. It will break though if you make a class inheriting from foo, since you will only be able to go one level up (i.e. back to foo).
There is no "through the object" way I know of to access hidden methods.
Just for kicks, here is a more robust version allowing chaining super calls using a dedicated class keeping tracks of super calls:
class Super:
def __init__(self, obj, counter=0):
self.obj = obj
self.counter = counter
def super(self):
return Super(self.obj, self.counter+1)
def __getattr__(self, att):
return getattr(super(type(self.obj).mro()[self.counter], self.obj), att)
class abc():
def xyz(self):
print("Class abc", type(self))
def super(self):
return Super(self)
class foo(abc):
def xyz(self):
print("class foo")
class buzz(foo):
def xyz(self):
print("class buzz")
buzz().super().xyz()
buzz().super().super().xyz()
results in
class foo
Class abc

How to force a python class to have a CLASS property? (not a INSTANCE property!!!)

I have googled around for some time, but what I got is all about INSTANCE property rather than CLASS property.
For example, this is the most-voted answer for question from stackoverflow
class C(ABC):
#property
#abstractmethod
def my_abstract_property(self):
return 'someValue'
class D(C)
def my_abstract_property(self):
return 'aValue'
class E(c)
# I expect the subclass should have this assignment,
# but how to enforce this?
my_abstract_property = 'aValue'
However, that is the INSTANCE PROPERTY case, not my CLASS PROPERTY case. In other words, calling
D.my_abstract_property will return something like <unbound method D.my_abstract_property>. Returning 'aValue' is what I expected, like class E.
Based on your example and comment to my previous reply, I've structured the following which works with ABC. :
from abc import ABC
class C(ABC):
_myprop = None
def __init__(self):
assert self._myprop, "class._myprop should be set"
#property
def myprop(self):
return self._myprop
class D(C):
_myprop = None
def __init__(self):
super().__init__()
class E(C):
_myprop = 'e'
def __init__(self):
super().__init__()
e = E()
print(e.myprop)
d = D()
print(d.myprop)
You are correct that there is no Python pre-scan that will detect another developer has not assigned a value to a class variable before initializing. The initializer will take care of notifying pretty quickly in usage.
You can use #classmethod decorator.
I come up with a tricky workaround.
class C(object):
myProp = None
def __init__(self):
assert self.myProp, 'you should set class property "name"'
class D(C):
def __init__(self):
C.__init__(self)
class E(C):
myProp = 'e'
def __init__(self):
C.__init__(self)
print(D.myProp)
print(E.myProp)
But it still has some problems:
D.myProp will not raise any exception to warn the developer about the constraint (assigning myProp as its class property), until the developer initialize an instance of his class.
abc module cannot work with this solution, which means loss of lots of useful features of that module

Handling custom __new__() and __del__() with inheritance

When I derive a class in Python, I need to call the Base.__init__(self) from the derived __init__(self) function like
class Base(object):
def __init__(self):
pass
class Der(Base):
def __init__(self) :
Base.__init__(self)
Do I need to do the same for __new__(self) and __del__(self) functions like
class Base(object):
def __new__(self):
pass
def __init__(self):
pass
def __del__(self) :
pass
class Der(Base):
def __new__(self):
Base.__new__(self)
def __init__(self) :
Base.__init__(self)
def __del__(self) :
Base.__del__(self)
I am wondering because nothing seems to go WRONG if I don't do that.
I am sure that python gc will take care, but is there anything I need to be worried about if I don't call them from Derived chain
The usage of __init__() and __del() is straightforward but not the __new()__
Since __new()__ returns an instance of the class, we need to call super().__new()__ till the object chain as given below
class Base(object):
def __new__(self):
return super().__new__(self)
class Derive(Base):
def __new__(self):
return super().__new__(self);
The __del()__ can be using similar to __init()__, calling Base.__del()__ is not mandatory unless and until some cleanup is required in base __del() function.
The correct way of writing the code asked in the question is
class Base(object):
def __new__(self):
return super().__new__(self)
def __init__(self):
self.Value = 200
def __del__(self):
pass
class Derive(Base):
def __new__(self):
return super().__new__(self);
def __init__(self):
Base.__init__(self)
def __del__(self):
Base.__del__(self)
It's always better not to implement __new()__ and __del()__ unless we really need it

Parent initializer not called in multi-level inheritence?

I have a class scheme with 2-levels of inheritance. My expectation is that each class constructor would run through- and yet the mid-level class constructor never seems to get hit. What's missing here?
class Base(object):
def __init__(self):
print "BASE"
class Next(Base):
def __init__(self):
super(Base, self).__init__()
print "NEXT"
class Final(Next):
def __init__(self):
super(Next, self).__init__()
print "FINAL"
f = Final()
Outputs:
BASE
FINAL
Why does "NEXT" not print??
You should be calling super() with the current class, not the parent.
class Base(object):
def __init__(self):
super(Base, self).__init__()
print "BASE"
class Next(Base):
def __init__(self):
super(Next, self).__init__()
print "NEXT"
class Final(Next):
def __init__(self):
super(Final, self).__init__()
print "FINAL"
f = Final()
At first glance this might seem redundant ("why can't it just get the class from self?") - but keep in mind that the same self is passed to all three of these __init__ methods when f is created, and that self is always of class Final. Thus, you have to pass super() the class that you want it to find the parent of.
class Base(object):
def __init__(self):
print "BASE"
class Next(Base):
def __init__(self):
super(Next, self).__init__()
print "NEXT"
class Final(Next):
def __init__(self):
super(Final, self).__init__()
print "FINAL"
f = Final()

Categories

Resources