Поведение Python super () не зависит - PullRequest
41 голосов
/ 15 марта 2012

По какой-то причине метод 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

Ответы [ 5 ]

57 голосов
/ 15 марта 2012

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

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

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

app = web.application(urls, globals(), autoreload=False)
12 голосов
/ 28 августа 2013

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

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

1 голос
/ 03 марта 2017

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

У меня просто была такая же проблема - запуск кода в блокноте 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, это решило проблему.

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

(Прошу прощения, если мой стиль не так, это мой первый пост о переполнении стека.:))

1 голос
/ 15 марта 2012

Я не уверен, почему происходит ошибка, но в качестве помощи для отладки вы можете заключить вызов в 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
...