Call a method in initialization without overriding base class's __init__ - python

I hope I make it clear in the title. I'm trying to inherit from list, and I want some of my own methods to be called when an instance of my class is created. However, I can't override list.__init__ since that would make me unable to use list's original methods. How can I accomplish this?

Simply call super.__init__ before / after you call your own methods:
class CustomList(list):
def __init__(self, *args):
super(CustomList, self).__init__(*args)
# call your own methods here

Related

Is it necessary to call super().__init__() explicitly in python?

I came from Java where we can avoid calling super class zero-argument constructor. The call to it is generated implicitly by the compiler.
I read this post about super() and now in question about is it really necessary to do something like this explicitly:
class A(object):
def __init__(self):
print("world")
class B(A):
def __init__(self):
print("hello")
super().__init__() #Do we get some Undefined Behavior if we do not call it explicitly?
If you override the __init__ method of the superclass, then the __init__ method of the subclass needs to explicitly call it if that is the intended behavior, yes.
Your mental model of __init__ is incorrect; it is not the constructor method, it is a hook which the constructor method calls to let you customize object initialization easily. (The actual constructor is called __new__ but you don't need to know this, and will probably never need to interact with it directly, let alone change it.)

Call parent class function

It is first time I try to use super(), I tried many little changes to this code, but with all I got error on line where super() is.
I saw similar questions on SO, but they are not working in my case or I do something wrong
Could you help me to call getMessagesBodies() from list() ?
class Gmail:
def getMessagesBodies(self, text):
return self.unpackPayload(text)
def unpackPayload(self, text):
return (text)
class getMessages:
def __init__(self):
self.service = auth()
def list(self,text):
return super(self).getMessagesBodies(text) # error here, how to call getMessagesBodies properly?
The problem is that you never specified what the parent class was for the getMessages class.
You should define the class like so:
class getMessages(Gmail):
Unless your child class is overriding the getMessagesBodies() function, you actually do not have to use super() to specify that you want to call the parent function. By using self.getMessagesBodies() in your child class it will automatically call the parent's function since the child inherits all the same functions from the parent.
So you can call the function without using super like:
self.getMessagesBodies(text)
Also, just a tip is that getMessages seems more like a function name then a class. Usually classes are fully capitalized and are an object, not an action.

How to call function that is in the other class python for pytest

I am trying to call the methods in CSVDatasource in my testing class by typing this code from ETL.CSVDatasource import CSVDatasource and to call the necessary methods but I have been receiving errors like TypeError: unbound method preprocess_col() must be called with CSVDatasource instance as first argument (got DataFrame instance instead)
http://imgur.com/8sfygtA -> Image of my coding path
Anyone can guide me on calling out the method in the other class so that I can call the method and do testing in my testing classs?
Thanks.
Generally, an instance of the class has to be created before calling the method of the class. For example,
class Person:
def __init__(self,name):
self.name=name
def who(self):
print 'I am {}'.format(self.name)
#staticmethod
def species():
print 'I am human.'
If we want to call the method who inside the class Person, we have to create an instance of class as follows:
if __name__=='__main__':
p1=Person('Qing Yong')
p1.who() #I am Qing Yong
However, if a method doesn't require self but you want to put it inside the class as this method may strongly related to you class in some senses. You may declare it as static method by using the decorator #staticmethod, like the method species
This static method can be called either through instance or through class directly as follows.
if __name__=='__main__':
p1.species() #I am human.
Person.species() #I am human.
Depending on the context of your code, you may choose either way to use the method inside your class.

Python class inheritance: AttributeError: '[SubClass]' object has no attribute 'xxx'

I have the following base class and subclass:
class Event:
def __init__(self, sr1=None, foobar=None):
self.sr1 = sr1
self.foobar = foobar
self.state = STATE_NON_EVENT
# Event class wrappers to provide syntatic sugar
class TypeTwoEvent(Event):
def __init__(self, level=None):
self.sr1 = level
self.state = STATE_EVENT_TWO
Further on in my code, I am inspecting an instance of a TypeTwoEvent class, checking for a field I know exists in the base class - I expected it to be defaulted to value None. However, my code raises the following exception:
AttributeError: 'TypeTwoEvent' object has no attribute 'foobar'
I was under the impression that the base class fields would be inherited by the subclass and that creating an instance of a subclass will instantiate the base class (and thus invoke its constructor) ...
What am I missing here? Why does TypeTwoEvent not have a foobar attribute - when the base class from which it is derived has a foobar attribute?
Your subclass should be:
class TypeTwoEvent(Event):
def __init__(self, level=None, *args, **kwargs):
super().__init__(*args, **kwargs)
self.sr1 = level
self.state = STATE_EVENT_TWO
Because you override the __init__ method, so you need to call the parent method if you want the parent behavior to happen.
Remember, __init__ is not a special method dispite its strange name. It's just the method automatically called after the object is created. Otherwise it's an ordinary method, and ordinary inheritance rules apply.
super().__init__(arguments, that, goes, to, parents)
is the syntax to call the parent version of the method.
For *args and **kwargs, it just ensures we catch all additional arguments passed to __init__ and pass it to the parent method, as you child method signature didn't do it and the parent need these arguments to work.
You're overriding the constructor (__init__) of the parent class. To extend it, you need to explicitly call the constructor of the parent with a super() call.
class TypeTwoEvent(Event):
def __init__(self, level=None, **kwargs):
# the super call to set the attributes in the parent class
super().__init__(**kwargs)
# now, extend other attributes
self.sr1 = level
self.state = STATE_EVENT_TWO
Note that the super call is not always at the top of the __init__ method in your sub-class. Its location depends on your situation and logic.
When the instance is created, its __init__ method is called. In this case, that is TypeTwoEvent.__init__. Superclass methods will not be called automatically because that would be immensely confusing.
You should call Event.__init__(self, ...) from TypeTwoEvent.__init__ (or use super, but if you're not familiar with it, read up on it first so you know what you're doing).
You need to call the __init__ method of the base class from the __init__ method of the inherited class.
See here for how to do this.
I've had the same problem, but in my case I put super().__init__() on the bottom of my derived class and that's why it doesn't work. Because I tried to use attributes that are not initialized.

Inherit from a built-in class

I would like to add some methods to the datetime.datetime object. It seems that we can only do that by inheriting from it and adding this new method. The problem is that this method need to update the day/month/year values of the base class and that i can't call the base init method with the new parameters.
How can I do this?
You can call the base class __init__ method.
class Foo(datetime.datetime):
def __init__(self, argument):
datetime.datetime.__init__(self, argument)
The key point here is that you need to call the __init__ method explicitly and you need to manually supply the first self argument that Python normally supplies for you.
Also, don't forget about the * and ** calling techniques to catch arguments that you don't want to deal with manually but that you still want to be able to pass to the parent constructor.

Categories