【问题标题】:Python super() behavior not dependablePython super() 行为不可靠
【发布时间】:2012-04-01 02:45:57
【问题描述】:

由于某种原因,super() 方法并不总是按预期运行,选择返回:

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

我了解错误的含义。我不明白为什么它会出现错误。这是正在破坏的代码的 sn-p。系统中的所有对象都是新样式对象。

真正有趣的是,这个错误并不总是出现。我不知道是什么原因造成的。 Retrieval 中的 super() 方法传递 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

【问题讨论】:

    标签: python inheritance superclass super


    【解决方案1】:

    您是否正在以某种方式重新加载模块?如果是这样,这可以解释这个错误。

    isinstance(self,DBAdminConnection) 在重新加载模块后可能会因为内存引用的更改而变为 false。

    编辑:如果您在 mod_wsgi 下运行 web.py 应用程序,请确保禁用自动重载:

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

    【讨论】:

    • 这是通过 webpy 运行的。所以这是一个确定的可能性。特别是因为如果我杀死应用程序实例并重新生成它,问题就会消失。哇。现在问题变成了如何解决它。
    • @TomThorogood:你是如何运行你的应用程序的?你在使用 mod_wsgi 吗?
    • 我不认为我正在这样做。我现在补充一下!我没有使用 mod_wsgi。我正在使用带有 spawn-fcgi 的 nginx。我会尝试禁用自动重载。非常感谢!
    • 我将把它标记为已解决;你所建议的一切都很有意义,我相信解决方案是唯一的(除非 webpy 中存在错误)。
    • 正如你所说的那样发生在我身上,因为我在 IPython 中使用了 %load_ext autoreload %autoreload 2 中的类
    【解决方案2】:

    我不确定为什么会发生错误,但作为调试的帮助,您可以将对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
    

    【讨论】:

    • 您的意思是您不确定吗?因为你让我一时抱了希望。 /咧嘴
    • 哈哈。不用担心!谢谢你的东西。我进行了一些调试;我只是在清理 SO 的代码。
    【解决方案3】:

    如果您在工作流程中使用 reload(),显然您还需要使用 super(self.__class__, self).__init__ 进行继承初始化。

    我怀疑你会发现这个错误与id(self.__class__) ==id(Retrieval) 失败相吻合。

    【讨论】:

    • super(self.__class__, self) 总是错误的。如果您进一步子类化,它将成为一个无限循环。
    • 如果不进一步子类化怎么办,有时可以吗?
    【解决方案4】:

    我刚刚遇到了同样的问题,在 jupyter notebook 中运行我的代码。我正在使用重新加载,所以我重新启动了我的内核以跟进 Eduardo Ivanec 的响应,尝试看看这是否是问题所在。然后我的代码坏了。我发现我的问题与多个继承层有关,其中底层定义在模块中的第二个底层之上

    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】:

      我遇到了同样的错误,然后我注意到我在同一个 file.py 中有重复的类(我的错误)。当我将第二个 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):
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-04
        • 1970-01-01
        • 1970-01-01
        • 2021-08-21
        • 1970-01-01
        • 2017-02-14
        相关资源
        最近更新 更多