I have an issue with inheritance.
This is my main program:
def main(argv):
rfp = reqboxfileparserng() # Inherits from reqboxfileparser()
rfp.importsdir = './data/'
if rfp.parsingasutf8_win():
rfp.parsefile("./data/LRCv12.txt")
Here are the classes:
class reqboxfileparser():
def __init__(self):
... removed code ...
# Init mmap
self.file = None
self.f = None
def parsefile(self, filename):
# Public
self.filename = filename
# Init mmap
self.file = codecs.open(filename, encoding='utf-8', mode='r') # open(filename, 'r')
self.f = mmap.mmap(self.file.fileno(), 0, access=mmap.ACCESS_READ)
self.f.seek(0) # rewind
# Parsing stuff
self.getfunlist()
self.vlog(VERB_MED, "len(fun) = %d" % (len(self.funlist)))
self.getfundict()
self.vlog(VERB_MED, "fundict = %s" % (self.fundict))
... rest of reqboxfileparser() class code removed ...
class reqboxfileparserng(reqboxfileparser, object):
def __init__(self):
# Public
reqboxfileparser.__init__(self)
self.fundict = {}
self.importsdir = ''
def getfunlist(self):
"""
Overrided method to load from a CSV file
"""
self.funlist = []
fh = open(self.importsdir + 'in-uc-objects.csv', 'rb')
f = csv.reader(fh, delimiter=',')
... rest of the code removed, it works fine ...
def getfundict(self):
"""
Fills the fundict property with a dict where each element is indexed
by the fun name and each value is an object from the model
"""
self.__fundict = {}
beginloc = self.bodystartloc()
# PROBLEM!
finalloc = super(reqboxfileparser, self).f.size() - 1
... rest of the code removed ...
As you can see I have two classes, the first is reqboxfileparser() and the second one is reqboxfileparserng() which inherits from the first one.
On the main program I call the method: parsefile(“./data/LRCv12.txt”) [not overrided] which later calls getfundict() [overrided] on the second class, but when I try to access f.size() it always fails with TypeError: must be type, not classobj.
It’s been a while since I don’t develop classes with inheritance but if I’m not wrong the concepts are right. I’m newbie to Python.
Any help please?
Thanks a lot.
There are two issues at hand here:
Super and old-style classes:
class reqboxfileparser():does not inherit fromobject, as a consequence,super(reqboxfileparser, self)will always yield the error:TypeError: must be type, not classobj.Improper super call in inheriting classes:
You’re doing
super(reqboxfileparser, self), but you’re passing the inherited class (reqboxfileparser) as first argument, not the inheriting class.As a consequence, Python would try to find a class that
reqboxfileparserinherits from which implements what you’re looking for you’re looking for:f.But that’s not want you want: what you want an ancestor of
reqboxfileparserngthat implementsf; that would bereqboxfileparser.Please have a look at the documentation for the most common
supercall syntax.Your solution
You probably guessed by now that you should be using
super(reqboxfileparserng, self)instead.Plus, you should always be using new-style classes (But that alone wouldn’t solve your issue, you would get a different error complaining that
AttributeError: 'super' object has no attribute 'f', which would beTrue, asobjectdoes not providef).One last thing…
But here, you have one last issue!
You’re trying to refer to
fwhich is an attribute of the instance of the child class. This attribute is not present when you use thesupercall as it’s not present in the class definition of the parent, which is the one thesupercall will use. (It’s in the__init__method)I won’t go into much more detail as to why this matters for super, but the idea is to basically use
superonly for stuff defined at class-level. Usually, methods are, so they’re great candidates forsupercalls.Here’s an example describing what I mean:
Overall, a
supercall is pretty similar to usingParentClass.stuff, only it deals with multiple inheritance better, and should be used for this reason.You can see that here,
reqboxfileparser.fwould raise anAttributeError.Footnote: a
classobjis an old-style class, atypeis a new-style class.