472,803 Members | 1,111 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,803 software developers and data experts.

Using super()

Hello,
I have a class called MyConfig, it is based on Python's
ConfigParser.ConfigParser.
It implements add_section(self, section), which is also implemented on
ConfigParser.ConfigParser, which I want to call.
So, reducing the problem to the bare minimum, the class (with a useless
add_section that shows the problem):
>>class MyConfig(ConfigParser):
.... def add_section(self, section):
.... super(MyConfig, self).add_section(section)
....

Create an object
>>m = MyConfig()
and call the problematic method:
>>m.add_section("blah")
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 3, in add_section
TypeError: super() argument 1 must be type, not classobj
>>>
Why is super() requiring a type ? doesn't it work with classes ? Is there a
way to achieve what I am trying to do (other than calling the specific
class that happens to be the parent today) ?

Thanks.
--
Pupeno <pu****@pupeno.com(http://pupeno.com)
Jul 19 '06 #1
7 1881
Pupeno írta:
Hello,
I have a class called MyConfig, it is based on Python's
ConfigParser.ConfigParser.
It implements add_section(self, section), which is also implemented on
ConfigParser.ConfigParser, which I want to call.
So, reducing the problem to the bare minimum, the class (with a useless
add_section that shows the problem):
The problem is that ConfigParser.ConfigParser is an old style class. It
is in the standard library, so I have no clue why. For old style
classes, you should directly call the ancestor class method.
For new style classes it works just fine:
class ConfigParser(object):
def add_section(self, section):
print section, "in ",self.__class__.__name__

class MyConfig(ConfigParser):
def add_section(self, section):
super(MyConfig, self).add_section(section)

m = MyConfig()
m.add_section("blah")
The output:

blah in MyConfig

Jul 19 '06 #2
Laszlo Nagy wrote:
Pupeno Ã*rta:
>Hello,
I have a class called MyConfig, it is based on Python's
ConfigParser.ConfigParser.
It implements add_section(self, section), which is also implemented on
ConfigParser.ConfigParser, which I want to call.
So, reducing the problem to the bare minimum, the class (with a useless
add_section that shows the problem):
The problem is that ConfigParser.ConfigParser is an old style class. It
is in the standard library, so I have no clue why. For old style
classes, you should directly call the ancestor class method.
For new style classes it works just fine:
class ConfigParser(object):
def add_section(self, section):
print section, "in ",self.__class__.__name__

class MyConfig(ConfigParser):
def add_section(self, section):
super(MyConfig, self).add_section(section)

m = MyConfig()
m.add_section("blah")
I see, thank you.

class MyConfig(ConfigParser, object):
def add_section(self, section)
super(MyConfig, self).add_section(section)

seems to work and as expected. Is there anything wrong with it ?
--
Pupeno <pu****@pupeno.com(http://pupeno.com)
Jul 19 '06 #3
I see, thank you.

class MyConfig(ConfigParser, object):
def add_section(self, section)
super(MyConfig, self).add_section(section)

seems to work and as expected. Is there anything wrong with it ?
I have never seen this before. :) I don't know the answer, but I'm
interested too.

Laszlo

Jul 19 '06 #4

Pupeno wrote:
I see, thank you.

class MyConfig(ConfigParser, object):
def add_section(self, section)
super(MyConfig, self).add_section(section)

seems to work and as expected. Is there anything wrong with it ?
Wow.

I highly recommend not doing this, unless the new type system was
designed to allow this sort of mixing, which I highly doubt. There are
some significant under-the-cover differences between old- and new-style
classes that could mess everything up when trying to mix them.
Carl Banks

Jul 19 '06 #5
Pupeno <pu****@pupeno.comwrote:
class MyConfig(ConfigParser, object):
def add_section(self, section)
super(MyConfig, self).add_section(section)

seems to work and as expected. Is there anything wrong with it ?
yes.

(1) There's a colon missing in the def-line. ;-)

(2) The folling doesn't work as you might expect:

----------------------------------------------8<---------------
from ConfigParser import ConfigParser
class MyConfig(ConfigParser, object):
def add_section(self, section):
print "in MyConfig"
super(MyConfig, self).add_section(section)

class AnotherConfig(object):
def add_section(self, section):
print "in AnotherConfig"
super(AnotherConfig, self).add_section(section)

class TheConfigIReallyUse(MyConfig, AnotherConfig):
def add_section(self, section):
print "in TheConfigConfigIReallyUse"
super(TheConfigIReallyUse, self).add_section(section)

a = TheConfigIReallyUse()

a.add_section(None)
---------------------------------------------->8---------------

If you call this little script, you get ...

----------------------------------------------8<---------------
in TheConfigConfigIReallyUse
in MyConfig
---------------------------------------------->8---------------

...., i. e. add_section in AnotherConfig won't be called.

The reason for this is, that the usage of "super" (or it's non-usage
in this case) is part of the interface of a class. ConfigParser doesn't
support super (as most if not all classes in the standard lib),
therefore it doesn't ensure AnotherConfig's add_section will be called
at an appropriate time. This call just gets lost.

In my world you should never user super with the only exception being
that you really know what you are doing. ;-) In fact, super is a cool
thing for non-trivial diamond shape inheritance (i.e. not counting
object to introduce the diamond shape, otherwise this would make every
multiple inheritance of new style classes a diamond shape). Even then
you have to be careful, that all methods must have the same signature
(*args and **kwargs may help you with this), because in the end you
never know which class calls which other class next. (Well, yes, you
may find out, but the next inheritance may break this again.)

In the end it comes down to:
(1) If you use diamond shape inheritance (or might in the
future), then use super.
(2) If your base classes support super, use super.
(3) If (1) goes without (2) be extra careful.
(4) Whatever you do, read the documentation of super and try to
understand what you are doing.
(5) If you want to know about the flamewar sourrounding this issue,
google for "python", "super" and "harmful"...

Cheers,
--Jan Niklas
Jul 19 '06 #6
Carl Banks ha scritto:
Pupeno wrote:
I see, thank you.

class MyConfig(ConfigParser, object):
def add_section(self, section)
super(MyConfig, self).add_section(section)

seems to work and as expected. Is there anything wrong with it ?

Wow.

I highly recommend not doing this, unless the new type system was
designed to allow this sort of mixing, which I highly doubt. There are
some significant under-the-cover differences between old- and new-style
classes that could mess everything up when trying to mix them.
I believe the new style system was designed to allows this sort of
mixing and
that there are no issues at all. A child of new style + old style is
simply a new
style class. If you do

class NewStyle(OldStyle, object):
pass

you will see that

type(NewStyle) == type

There should be something more on
http://www.python.org/download/relea...2.3/descrintro

(I have seen somewhere how type.__new__ works, and how the metaclass
is chosen, so I am pretty sure sure there are no issue, at least for
pure Python
classes).

Michele Simionato

Jul 20 '06 #7
Michele Simionato ha scritto:
I believe the new style system was designed to allows this sort of
mixing and
that there are no issues at all.
Thinking a bit more, there are no issues at all if you know what a new
style class is and if you do not expect it to work as an old-style one
;) For the benefit of the OP, it may be useful to notice that there are
a few differences, most notably on how special methods works. Here is
an example:

class Old:
pass

old = Old()

old.__str__ = lambda : 'hello!'

print old # special methods defined on the instance are recognized

class New(Old, object):
pass

new = New()

new.__str__ = lambda : 'hello!' # special methods defined on the
instance are not recognized

print new
HTH,

Michele Simionato

Jul 20 '06 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: James Hong | last post by:
Help please, I try to sending an email from my html page using the java applet. but it give error on most of the PC only very few work, what is the error i make the java applet show as below ...
0
by: daishi | last post by:
Hi, The following code appears to be doing what I'd expect, but I'm wondering if someone could confirm that there aren't any "gotchas" hidden in using methods accessed in this way. In...
4
by: Kerim Borchaev | last post by:
Hello! Always when I use "super" I create a code duplication because class used as first arg to "super" is always the class where the method containing "super" was defined in: ''' class C:...
11
by: Nicolas Lehuen | last post by:
Hi, I hope this is not a FAQ, but I have trouble understanding the behaviour of the super() built-in function. I've read the excellent book 'Python in a Nutshell' which explains this built-in...
0
by: Michele Simionato | last post by:
Here is an idea for a nicer syntax in cooperative method calls, which is not based on Guido's "autosuper" example. This is just a hack, waiting for a nicer "super" built-in ... Here is example...
0
by: Delaney, Timothy C (Timothy) | last post by:
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/286195 This is a new version of super that automatically determines which method needs to be called based on the existing stack frames....
16
by: Simon Wittber | last post by:
I've noticed that a few ASPN cookbook recipes, which are recent additions, use classic classes. I've also noticed classic classes are used in many places in the standard library. I've been...
9
by: Mike Krell | last post by:
I'm reading Alex Martelli's "Nutshell" second edition. In the section called "Cooperative superclass method calling", he presents a diamond inheritance hierachy: class A(object): def...
12
by: iu2 | last post by:
Hi I'm trying to make a method call automatically to its super using this syntax: class A: chained = def pr(self): print 'Hello from A'
0
by: erikbower65 | last post by:
Using CodiumAI's pr-agent is simple and powerful. Follow these steps: 1. Install CodiumAI CLI: Ensure Node.js is installed, then run 'npm install -g codiumai' in the terminal. 2. Connect to...
0
linyimin
by: linyimin | last post by:
Spring Startup Analyzer generates an interactive Spring application startup report that lets you understand what contributes to the application startup time and helps to optimize it. Support for...
0
by: kcodez | last post by:
As a H5 game development enthusiast, I recently wrote a very interesting little game - Toy Claw ((http://claw.kjeek.com/))。Here I will summarize and share the development experience here, and hope it...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Sept 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM) The start time is equivalent to 19:00 (7PM) in Central...
14
DJRhino1175
by: DJRhino1175 | last post by:
When I run this code I get an error, its Run-time error# 424 Object required...This is my first attempt at doing something like this. I test the entire code and it worked until I added this - If...
0
by: Rina0 | last post by:
I am looking for a Python code to find the longest common subsequence of two strings. I found this blog post that describes the length of longest common subsequence problem and provides a solution in...
5
by: DJRhino | last post by:
Private Sub CboDrawingID_BeforeUpdate(Cancel As Integer) If = 310029923 Or 310030138 Or 310030152 Or 310030346 Or 310030348 Or _ 310030356 Or 310030359 Or 310030362 Or...
0
by: lllomh | last post by:
Define the method first this.state = { buttonBackgroundColor: 'green', isBlinking: false, // A new status is added to identify whether the button is blinking or not } autoStart=()=>{
0
by: lllomh | last post by:
How does React native implement an English player?

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.