ChatGPT解决这个技术问题 Extra ChatGPT

super() fails with error: TypeError "argument 1 must be type, not classobj" when parent does not inherit from object

I get some error that I can't figure out. Any clue what is wrong with my sample code?

class B:
    def meth(self, arg):
        print arg

class C(B):
    def meth(self, arg):
        super(C, self).meth(arg)

print C().meth(1)

I got the sample test code from help of 'super' built-in method.

Here is the error:

Traceback (most recent call last):
  File "./test.py", line 10, in ?
    print C().meth(1)
  File "./test.py", line 8, in meth
    super(C, self).meth(arg)
TypeError: super() argument 1 must be type, not classobj

FYI, here is the help(super) from python itself:

Help on class super in module __builtin__:

class super(object)
 |  super(type) -> unbound super object
 |  super(type, obj) -> bound super object; requires isinstance(obj, type)
 |  super(type, type2) -> bound super object; requires issubclass(type2, type)
 |  Typical use to call a cooperative superclass method:
 |  class C(B):
 |      def meth(self, arg):
 |          super(C, self).meth(arg)
 |
Meth?? Is that a programming term, or... y'know? Please clarify.
@Cplusplusplus: probably stands for Method ;-)

s
steveha

Your problem is that class B is not declared as a "new-style" class. Change it like so:

class B(object):

and it will work.

super() and all subclass/superclass stuff only works with new-style classes. I recommend you get in the habit of always typing that (object) on any class definition to make sure it is a new-style class.

Old-style classes (also known as "classic" classes) are always of type classobj; new-style classes are of type type. This is why you got the error message you saw:

TypeError: super() argument 1 must be type, not classobj

Try this to see for yourself:

class OldStyle:
    pass

class NewStyle(object):
    pass

print type(OldStyle)  # prints: <type 'classobj'>

print type(NewStyle) # prints <type 'type'>

Note that in Python 3.x, all classes are new-style. You can still use the syntax from the old-style classes but you get a new-style class. So, in Python 3.x you won't have this problem.


interesting, I found this exact problem running bottle.py (bottlepy.org) which throws a similar error (TypeError: must be type, not classobj) running on Py27 but not Py33.
In Python 3.x, there are no more "old-style" classes. Code using the "old-style" declaration still declares a "new-style" class, so this error cannot occur in Python 3.x.
If class B is not available for you to edit, then you must edit class A to not try to use super(); class A must be made to work with an "old-style" class, and possibly the best way to do that would be to make class A be itself an "old-style" class. Of course I recommend just upgrading your whole program to run in Python 3.x, so that all classes will be new-style no matter what you do; if that option is available it's the best option.
I have the same issue, but my base class is declared like class B(object):. I'm getting this error due to using @mock.patch('module.B', autospec=B) just before my test case. Any thoughts on how to fix this?
W
Wilfred Hughes

Also, if you can't change class B, you can fix the error by using multiple inheritance.

class B:
    def meth(self, arg):
        print arg

class C(B, object):
    def meth(self, arg):
        super(C, self).meth(arg)

print C().meth(1)

I could not help to leave a comment, this one should be accepted as 'standard' answer.
For future googlers stuck on Python 2.6: this is the answer you probably want! When you can't change the base class (e.g. you're subclassing a standard library class), this change to your own class fixes super().
It worked fine to me, Can you somebody explain how it works?
@subro, this makes your class a "new-style" class (where class object is of type type) while still subclassing an "old-style" class (whose class object is of type classobj). super() works with new-style classes but not with old-style classes.
y
yanghaogn

If the python version is 3.X, it's okay.

I think your python version is 2.X, the super would work when adding this code

__metaclass__ = type

so the code is

__metaclass__ = type
class B:
    def meth(self, arg):
        print arg
class C(B):
    def meth(self, arg):
        super(C, self).meth(arg)
print C().meth(1)

M
MSeifert

I was also faced by the posted issue when I used python 2.7. It is working very fine with python 3.4

To make it work in python 2.7 I have added the __metaclass__ = type attribute at the top of my program and it worked.

__metaclass__ : It eases the transition from old-style classes and new-style classes.