Подтвердить что ты не робот

Поведение Python super() не является надежным

По какой-то причине метод super() не всегда ведет себя так, как ожидалось, предпочитая возвращать:

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

Я понимаю, что означает ошибка. Я не понимаю, почему это происходит как ошибка. Вот фрагмент кода, который ломается. Все объекты в системе - это новые объекты стиля.

Что действительно интересно, так это то, что эта ошибка не всегда появляется. Я не знаю, что вызывает это. Метод super() в Retrieval передает класс Retrieval, а затем сам по себе как объект, который, насколько мне известно, точно соответствует super().

Любые мысли вообще?

В файле DBConnection.py:

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

В файле 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
4b9b3361

Ответ 1

Вы перезагружаете модули как-то посреди вещей? Если это так, это может объяснить эту ошибку.

isinstance(self,DBAdminConnection) может стать ложным после перезагрузки модулей из-за изменений в ссылках на память, по-видимому.

Изменить: если вы используете приложение web.py в mod_wsgi, убедитесь, что вы отключили автозагрузку:

app = web.application(urls, globals(), autoreload=False)

Ответ 2

Если вы используете reload() как часть вашего рабочего процесса, вам, вероятно, также нужно использовать super(self.__class__, self).__init__ для инициализации наследования.

Я подозреваю, что эта ошибка совпадает с ошибкой id(self.__class__) ==id(Retrieval).

Ответ 3

Я не уверен, почему происходит ошибка, но в качестве помощи для отладки вы можете связать вызов super в блоке try/except и сделать дамп данных при возникновении исключения. Что-то вроде этого:

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

Ответ 4

У меня была одна и та же проблема, запустив мой код в ноутбуке jupyter. Я использовал reload, поэтому я перезапустил свое ядро, чтобы следить за ответом Эдуардо Ивенека, чтобы попытаться посмотреть, не возникла ли эта проблема. Тогда мой код сломался. Я обнаружил, что моя проблема связана с несколькими уровнями наследования, где нижний слой был определен над вторым нижним уровнем в модуле.

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'''

Когда я переместил MyClass4 под MyClass3, он исправил проблему.

Вероятно, это ошибка новобранец, поэтому он, вероятно, не решит причину исходной проблемы выше, но я думал, что опубликую ее в случае, если есть другие новички, такие как я, которые совершают ту же ошибку.

(Извиняется, если мой стиль неправильный, это мой первый пост в Stack Overflow.:))

Ответ 5

У меня была такая же ошибка, и я заметил, что у меня был дублирующий класс (моя ошибка) в том же файле. Ошибка исчезла, когда я переименовал второй класс A в класс 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):