Python super() behavior not dependable

2020-05-19 03:42发布

For some reason, the super() method is not always behaving as expected, opting to return:

TypeError('super(type, obj): obj must be an instance or subtype of type)'

I understand what the error means. I do not understand why it is coming up as an error. Here's the snippet of code that is breaking. All objects in the system are new style objects.

What's really interesting is that this error does not always show up. I don't know what's causing it. The super() method in Retrieval is passing the Retrieval class, and then itself as an object, which is, as far as I'm aware,exactly how super() is supposed to be invoked.

Any thoughts at all?

In file DBConnection.py:

class DBAdminConnection(object):
    def __init__(self):
        self.user = DBUserConnection().user 
        self.submissions = DBSubmissionConnection()

In file Retrieval.py

class Retrieval(DBConnection.DBAdminConnection): 
    def __init__(self, username=None, password=None, unique_key=None):
        super(Retrieval,self).__init__()
        if username and password:
            self.username = username
            self.user.login(username,password, config.DATABASE)
            if self.user.error:
                raise UserLoginError(username)
        self.unique_key = unique_key

5条回答
在下西门庆
2楼-- · 2020-05-19 04:23

If you are using reload() as part of your workflow, you apparently need to also use super(self.__class__, self).__init__ for inheritance initialization.

I suspect you will find this bug coincides with id(self.__class__) ==id(Retrieval) failing.

查看更多
甜甜的少女心
3楼-- · 2020-05-19 04:26

Are you reloading modules somehow in the middle of things? If so, that may explain this error.

isinstance(self,DBAdminConnection) may become false after reloading modules because of the changes to memory references, apparently.

Edit: if you're running your web.py app under mod_wsgi, make sure you're disabling autoreload:

app = web.application(urls, globals(), autoreload=False)
查看更多
来,给爷笑一个
4楼-- · 2020-05-19 04:35

I'm not sure why the error is happening, but as an aid to debugging you could wrap the call to super in a try/except block and do a data dump when the exception is raised. Something like this:

class Retrieval(DBConnection.DBAdminConnection): 
    def __init__(self, username=None, password=None, unique_key=None):
        try:
            super(Retrieval,self).__init__()
        except TypeError, e:
            print "Failure initialising Retrieval --> self: %r"
            raise
        if username and password:
            self.username = username
            self.user.login(username,password, config.DATABASE)
            if self.user.error:
                raise UserLoginError(username)
        self.unique_key = unique_key
查看更多
看我几分像从前
5楼-- · 2020-05-19 04:41

I had the same error then i noticed that i had duplicate class (my mistake) within the same file.py. Error disappeared when i renamed the second class A to class B

#Just some example below, not real code
class A (object):

    def fun(self):
        super(A, self).fun()

class A (object): ##This second class with same name (A) caused the error

   def some_fun(self,x,y):
查看更多
SAY GOODBYE
6楼-- · 2020-05-19 04:49

I just had the same problem, running my code in jupyter notebook. I was using reload, so I restarted my kernel to follow up on Eduardo Ivanec's response to try and see if this was the problem. Then my code broke. I discovered my problem was related to several layers of inheritance, where the bottom layer was defined above the second bottom layer in the module.

class MyClass1(object):
'''example class 1'''

class MyClass2(MyClass1):
'''example class 2'''
    def __init__(self):
    super(MyClass2, self).__init__()

class MyClass4(MyClass3):
'''example class 4 - no __init__ definition'''

class MyClass3(MyClass2):
'''example class 3 - no __init__ definition'''

When I moved MyClass4 underneath MyClass3, it fixed the problem.

This is probably a rookie mistake, so it probably won't resolve the cause of the original problem above, but I thought I would post in case there are other rookies out there, like me, who are making the same mistake.

(Apologies if my style is wrong, this is my first post on Stack Overflow. :))

查看更多
登录 后发表回答