Python super(type, obj): obj 必须是 type 的实例或子类型

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/43751455/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 23:22:05  来源:igfitidea点击:

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

pythondjango

提问by Chaklader Asfak Arefe

I work on a small Djangoapp and get an error tells me, super(type, obj): obj must be an instance or subtype of type. I get it from the views.pyfile after introducing the function get_object_or_404. The views.pyfile provided below,

我在开发一个小Django应用程序并收到一个错误消息,告诉我super(type, obj): obj must be an instance or subtype of type. views.py引入函数后我从文件中得到它get_object_or_404。下面views.py提供的文件,

from django.shortcuts import render, get_object_or_404    
from django.http import HttpResponse, HttpResponseRedirect     
from django.views import View     
from .models import URL


# function based view 
def redirect_view(request, shortcode=None, *args, **kwargs):
    obj = get_object_or_404(URL, shortcode=shortcode)
    return HttpResponse("Hello World, the shortcode is {shortcode}".format(shortcode = obj.url))


# class based view 
class ShortenerView(View):

    def get(self, request, shortcode=None,  *args, **kwargs):
        obj = get_object_or_404(URL, shortcode=shortcode)
        return HttpResponse("Hello World 1, the shortcode is {shortcode}".format(shortcode = obj.url))

    def post(self, request, *args, **kwargs):
        return HttpResponse()

the full error message is here,

完整的错误信息在这里,

TypeError at /b/p6jzbp/
super(type, obj): obj must be an instance or subtype of type
Request Method: GET
Request URL:    http://127.0.0.1:8000/b/p6jzbp/
Django Version: 1.11
Exception Type: TypeError
Exception Value:    
super(type, obj): obj must be an instance or subtype of type
Exception Location: /Users/Chaklader/Documents/Projects/UrlShortener/src/shortener/models.py in all, line 18

The line 18in the models.pyis qs_main = super(URL, self).all(*args, **kwargs)and the models.pyfile is here,

line 18models.pyqs_main = super(URL, self).all(*args, **kwargs)models.py文件是在这里,

#  will look for the "SHORTCODE_MAX" in the settings and 
#  if not found, will put the value of 15 there 
SHORTCODE_MAX = getattr(settings, "SHORTCODE_MAX", 15)



class UrlManager(models.Manager):

    def all(self, *args, **kwargs):
        qs_main = super(URL, self).all(*args, **kwargs)
        qs      = qs_main.filter(active = True)
        return qs

    def refresh_shortcodes(self, items = None):

        qs = URL.objects.filter(id__gte=1)
        new_codes = 0

        if items is not None and isinstance(items, int):
            qs = qs.order_by('-id')[:items]

        for q in qs:
            q.shortcode = create_shortcode(q)
            print (q.id, " ", q.shortcode)
            q.save()
            new_codes += 1

        return "# new codes created {id}".format(id = new_codes)


class URL(models.Model):

    url         =  models.CharField(max_length = 220, )
    shortcode   =  models.CharField(max_length = SHORTCODE_MAX, blank = True, unique = True)
    updated     =  models.DateTimeField(auto_now = True)
    timestamp   =  models.DateTimeField(auto_now_add = True)
    active      = models.BooleanField(default = True)

    objects = UrlManager()

    def save(self, *args, **kwargs):

        if self.shortcode is  None or self.shortcode == "":
            self.shortcode = create_shortcode(self)

        super(URL, self).save(*args, **kwargs)

    def __str__(self):
        return str(self.url)

    def __unicode__(self):
        return str(self.url)

    # class Meta:
    #   ordering = '-id'

Can someone explain the the reason of error to me and how to solve it? I'm open to provide more informations IF required.

有人可以向我解释错误的原因以及如何解决吗?如果需要,我愿意提供更多信息。

采纳答案by Moses Koledoye

You should call superusing the UrlManagerclass as first argument not the URLmodel. supercannot called be with an unrelatedclass/type:

您应该调用super使用UrlManager类作为第一个参数而不是URL模型。super不能用不相关的类/类型调用:

From the docs,

从文档中,

super(type[, object-or-type]): Return a proxy object that delegates method calls to a parent or sibling class of type.

super(type[, object-or-type]): 返回一个代理对象,该对象将方法调用委托给类型的父类或兄弟类。

So you cannotdo:

所以你不能这样做:

>>> class D:
...    pass
... 
>>> class C:
...    def __init__(self):
...        super(D, self).__init__()
... 
>>> C()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in __init__
TypeError: super(type, obj): obj must be an instance or subtype of type

You should do:

你应该做:

qs_main = super(UrlManager, self).all(*args, **kwargs)

Or in Python 3:

或者在 Python 3 中:

qs_main = super().all(*args, **kwargs)

回答by O?uz ?erbetci

Another way this error can occur is when you reload the module with the class in a Jupiter notebook.

发生此错误的另一种方式是在 Jupiter 笔记本中使用类重新加载模块时。

Easy solution is to restart the kernel.

简单的解决方案是重新启动内核。

http://thomas-cokelaer.info/blog/2011/09/382/

http://thomas-cokelaer.info/blog/2011/09/382/

Check out @Mike W's answerfor more detail.

查看@Mike W 的答案以了解更多详细信息。

回答by Mike W

Elaborating in @O?uz ?erbetci's answer, in python3 (not necessary only in Jupyter), when there is the need to reload a library, for example we have class Parentand class Childdefined as

在@O?uz ?erbetci 的回答中详细说明,在 python3 中(仅在 Jupyter 中不需要),当需要重新加载库时,例如我们有class Parentclass Child定义为

class Parent(object):
    def __init__(self):
        # do something

class Child(Parent):
    def __init__(self):
        super(Child, self).__init__(self)

then if you do this

那么如果你这样做

import library.Child
reload(library)

Child()

you will get TypeError: super(type, obj): obj must be an instance or subtype of type, the solution is just to re import the class after the reload

你会得到TypeError: super(type, obj): obj must be an instance or subtype of type,解决方案只是在重新加载后重新导入类

import library.Child
reload(library)
import library.Child

Child()

回答by Eldamir

Another interesting way is if a merge of branches has duplicated the class, so that in the file you have two definitions for the same name, e.g.

另一个有趣的方式是如果分支的合并复制了类,那么在文件中你有两个同名的定义,例如

class A(Foo):
    def __init__(self):
        super(A, self).__init__()
        #...

class A(Foo):
    def __init__(self):
        super(A, self).__init__()
        #...

If you try to create an instance from a static reference to the first definition of A, once it tries to call super, inside the __init__method, Awill refer to the second definition of A, since it has been overwritten. The solution - ofcourse - is to remove the duplicate definition of the class, so it doesn't get overwritten.

如果您尝试从对 A 的第一个定义的静态引用创建实例,一旦它尝试调用super,在__init__方法内部A将引用 的第二个定义A,因为它已被覆盖。解决方案——当然——是删除类的重复定义,这样它就不会被覆盖。

This may seem like something that would never happen, but it just happened to me, when I wasn't paying close enough attention to the merge of two branches. My tests failed with the error message described in the question, so I thought I'd leave my findings here, even though it doesn't exactly answer the specific question.

这似乎是永远不会发生的事情,但它只是发生在我身上,当时我没有对两个分支的合并给予足够的关注。我的测试因问题中描述的错误消息而失败,所以我想我会在这里留下我的发现,即使它没有完全回答特定问题。

回答by pymen

For Jupyter onlyYou can get his issue in because reloadlogic have some bugs (issue)

仅适用于 Jupyter您可以解决他的问题,因为reload逻辑有一些错误(问题

Here is a simple solution/workaround that works for me until issue is not fixed

这是一个简单的解决方案/解决方法,在问题未解决之前对我有用

  1. Add typo like 1001xxat the bottom of the file which you call in the cell
  2. Run your cell - you will see some exception, just skip it
  3. Remove typo which was added on step 1
  4. Run the cell
  5. Profit
  1. 1001xx在您在单元格中调用的文件底部添加错字
  2. 运行你的单元格 - 你会看到一些异常,跳过它
  3. 删除在步骤 1 中添加的错字
  4. 运行单元格
  5. 利润