Solved

python subclass with extra arguments?

Posted on 2013-10-23
7
1,868 Views
Last Modified: 2013-10-25
Hi,

I'm trying to figure out Python's subclassing when the subclass requires additional arguments.  I've put together a very simple program just to try things out, but I can't seem to get the syntax Python likes.
class Abc(object):

    def __init__(self,a,b,c=None):
        self.a = a
        self.b = b
        self.c = c

    def pr(self):
        print "{}, {}, {}".format(self.a,self.b,self.c)

Open in new window

#------------------Different file
import abc_class as ac

class Abcd(ac.Abc):

    def __init__(self, a,b,c,d):  #What goes here for a, b, c and d?

       # Tried everything here.  What's this super call supposed to look?
        super( Abcd, self,a).__init__()like?

if __name__ == '__main__':

    x = Abcd(4,5,6)
    x.pr()

Open in new window

I subclassed Abc from object because I read something about old vs. new style classes and the new style require the base class object (I'm obviously no expert ...)

I need to instantiate the Abcd class, which should call the super's init and use the extra arguments for additional processing.  However, no matter how many arguments I add or remove, it always says I'm giving too many or too few.

What's the syntax if I want the Abcd class to have an argument 'd' in addition to a,b and c and call the super's init with a, b and c?

Thanks!
0
Comment
Question by:ugeb
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
7 Comments
 
LVL 29

Accepted Solution

by:
pepr earned 500 total points
ID: 39596539
There can be several approaches to your problem. Firstly, it depends on whether you need to use a specific version of Python.

Looking at the syntax, you are using Python 2.7 (or you should use). Then you should write it like:
class Base(object):

    def __init__(self, a, b, c=None):
        self.a = a
        self.b = b
        self.c = c

    def pr(self):
        print '{}, {}, {}'.format(self.a, self.b, self.c)
        
        
class Derived(Base):

    def __init__(self, a, b, c, d):
         super(Derived, self).__init__(a, b, c)
         self.d = d       
         
    def pr(self):
        print '{}, {}, {}, {}'.format(self.a, self.b, self.c, self.d)
        
        
if __name__ == '__main__':
    
    bas = Base(1, 2, 3)
    bas.pr()
    
    der = Derived(1, 2, 3, 4)
    der.pr()  

Open in new window

However, the Python 3 removes the visibility of the term "new-style classes", and does not force you to use object as a base class. All classes are of new-style, but the syntax is as simple as in the Python 2 old-style. Also the super() can be used more elegantly -- it does not require any argument. Notice also, that it is better to define your own __str__() method implementation and use the print command for the object instead of calling the .pr() method of the object. Then you can redefine the __str__ of the derived class using the result of __str__ from the base class. (This holds also for Python 2.):
class Base:

    def __init__(self, a, b, c=None):
        self.a = a
        self.b = b
        self.c = c

    def __str__(self):
        return '{}, {}, {}'.format(self.a, self.b, self.c)

        
class Derived(Base):

    def __init__(self, a, b, c, d):
         super().__init__(a, b, c)    # pass the to the Base initializer
         self.d = d                   # add the extra variable
         
    def __str__(self):
        # Here string representation of the Base part with added self.d
        return super().__str__() + ', {}'.format(self.d) 

        
if __name__ == '__main__':
    
    bas = Base(1, 2, 3)
    print(bas)
    
    der = Derived(1, 2, 3, 4)
    print(der)      

Open in new window

If you still need to use Python 2.7, then I recommend not to use super(), use the old style classes and name the base class explicitly:
class Base:

    def __init__(self, a, b, c=None):
        self.a = a
        self.b = b
        self.c = c

    def __str__(self):
        return '{}, {}, {}'.format(self.a, self.b, self.c)


class Derived(Base):

    def __init__(self, a, b, c, d):
         Base.__init__(self, a, b, c)
         self.d = d

    def __str__(self):
        # Here string representation of the Base part with added self.d
        return Base.__str__(self) + ', {}'.format(self.d)


if __name__ == '__main__':

    bas = Base(1, 2, 3)
    print bas

    der = Derived(1, 2, 3, 4)
    print der

Open in new window

Feel free to ask what is not understandable.
0
 
LVL 17

Expert Comment

by:gelonida
ID: 39597335
minor comment:

you can also use new style classes (so Base inherits from object)
and not use super()

so:
class Base(object):
. . . 

class  Derived(Base):
    def __init__(self, a, b, c, d):
         Base.__init__(self, a, b, c)

Open in new window

0
 
LVL 29

Expert Comment

by:pepr
ID: 39597430
I agree, but why would I use object explicitly? There should be a specific reason for making things more complicated.
0
Get 15 Days FREE Full-Featured Trial

Benefit from a mission critical IT monitoring with Monitis Premium or get it FREE for your entry level monitoring needs.
-Over 200,000 users
-More than 300,000 websites monitored
-Used in 197 countries
-Recommended by 98% of users

 
LVL 17

Expert Comment

by:gelonida
ID: 39597633
a few reasons (though in many cases they don't really matter, but well . . ):
- in order to avoid any subtle differences in behaviour which one might forget / overlook.
   ( special methods / descriptors / method resolution order in case of multiple inheritance )
- Python 3 will only have the behaviour of old style classes
- decorators like @classmethod and @staticmethod
- just out of habit ;-)
- for consistency reasons

What can also be annoying is if you want to inherit from an old style class and suddenly some features don't work  (descriptors) in derived classes.

At least in our team (using Python 2.7) we don't use any old style classes for our own code
as is the official recommendation.
0
 
LVL 11

Author Closing Comment

by:ugeb
ID: 39598177
Yes indeed it is Python 2.7 and your solution works well.  Thanks to both!
0
 
LVL 29

Expert Comment

by:pepr
ID: 39599790
why would I use object explicitly?
- Python 3 will only have the behaviour of old style classes

The official documentation says for Python 3 (http://docs.python.org/3/reference/compound_stmts.html#class-definitions)
Classes without an inheritance list inherit, by default, from the base class object; hence,

class Foo:
    pass

is equivalent to

class Foo(object):
    pass

0
 
LVL 17

Expert Comment

by:gelonida
ID: 39599799
- Python 3 will only have the behaviour of old style classes

was a typo.
I wanted to write" new style" of course.
Thus in order to have most similiar behaviour for code potentially running on 2.7 and 3.0 I always inherit from object .


Whatever. As I said in my previous post. in most real life cases it won't make a difference.
I'm just being very conservative.
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Since upgrading to Office 2013 or higher installing the Smart Indenter addin will fail. This article will explain how to install it so it will work regardless of the Office version installed.
Whether you've completed a degree in computer sciences or you're a self-taught programmer, writing your first lines of code in the real world is always a challenge. Here are some of the most common pitfalls for new programmers.
In this fifth video of the Xpdf series, we discuss and demonstrate the PDFdetach utility, which is able to list and, more importantly, extract attachments that are embedded in PDF files. It does this via a command line interface, making it suitable …
With the power of JIRA, there's an unlimited number of ways you can customize it, use it and benefit from it. With that in mind, there's bound to be things that I wasn't able to cover in this course. With this summary we'll look at some places to go…

623 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question