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

Are*_*efe 30 python django

我在一个小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()
Run Code Online (Sandbox Code Playgroud)

完整的错误消息在这里,

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
Run Code Online (Sandbox Code Playgroud)

line 18models.pyIS qs_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'
Run Code Online (Sandbox Code Playgroud)

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

Oğu*_*tci 50

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

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

  • 每次都把我绊倒。:) (5认同)
  • 每年必须读一次这篇文章,就像我的 Python 圣诞节一样。有什么办法可以永久解决这个问题吗? (5认同)
  • 我以为我也疯了,但这就是为什么我不断收到此错误的原因。只需退出并重新进入Python即可对其进行修复。谢谢! (2认同)

Mos*_*oye 17

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

从文档中,

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

所以,你不能这样做:

>>> 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
Run Code Online (Sandbox Code Playgroud)

你应该做:

qs_main = super(UrlManager, self).all(*args, **kwargs)
Run Code Online (Sandbox Code Playgroud)

或者在Python 3中:

qs_main = super().all(*args, **kwargs)
Run Code Online (Sandbox Code Playgroud)

  • super 不应该以父类作为第一个参数来调用 (2认同)

Mik*_*e W 12

在阐述@O?UZ?erbetci的回答,在python3(仅在Jupyter没有必要),当有重新加载库的需要,例如我们class Parentclass Child定义

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

class Child(Parent):
    def __init__(self):
        super(self,Child).__init__(self)
Run Code Online (Sandbox Code Playgroud)

那么如果你这样做

import library.Child
reload(library)

Child()
Run Code Online (Sandbox Code Playgroud)

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

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

Child()
Run Code Online (Sandbox Code Playgroud)

  • 你好,你知道这如何与自动重新加载魔法一起使用吗?`%reload_ext 自动重载`, `%autoreload 2` (2认同)

pym*_*men 8

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

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

  1. 1001xx在您在单元格中调用的文件底部添加错字
  2. 运行你的单元格 - 你会看到一些异常,跳过它
  3. 删除在步骤 1 中添加的错字
  4. 运行单元格
  5. 利润


小智 7

我找到的解决这个问题的最佳解决方案只能使用 python 3。然后你不需要指定“super”的参数,那么你就不会再像这样编写你的类时出现错误:

class D:
   pass

class C(D):
    def __init__(self):
        super().__init__()# no arguments given to super()
Run Code Online (Sandbox Code Playgroud)


Eld*_*mir 6

另一种有趣的方法是,如果分支的合并重复了该类,那么在文件中您有相同名称的两个定义,例如

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

class A(Foo):
    def __init__(self):
        super(A, self).__init__()
        #...
Run Code Online (Sandbox Code Playgroud)

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

这看起来似乎永远不会发生,但它就发生在我身上,当时我没有足够关注两个分支的合并。我的测试因问题中描述的错误消息而失败,所以我想我应该将我的发现留在这里,即使它没有完全回答具体问题。