super(type, obj): obj moet een instantie of subtype van het type zijn

Ik werk aan een kleine Django-app en krijg een foutmelding die me vertelt: super(type, obj): obj must be an instance or subtype of type. Ik haal het uit het bestand views.pynadat ik de functie get_object_or_404heb geïntroduceerd. Het bestand views.pyhieronder,

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()

de volledige foutmelding staat hier,

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

De line 18in de models.pyis qs_main = super(URL, self).all(*args, **kwargs)en het bestand models.pyis hier,

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

Kan iemand mij de reden van de fout uitleggen en hoe ik deze kan oplossen? Ik sta open om meer informatie te verstrekken ALS dat nodig is.


Antwoord 1, autoriteit 100%

Een andere manier waarop deze fout kan optreden, is wanneer u de module opnieuw laadt met de klasse in een Jupiter-notebook.

Eenvoudige oplossing is om de kernel opnieuw te starten.

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

Bekijk het antwoordvan @Mike W voor meer informatie.


Antwoord 2, autoriteit 24%

Je moet superaanroepen met de klasse UrlManagerals eerste argument, niet het URL-model. superkan niet worden aangeroepen met een niet-verwanteklasse/type:

Uit de documenten,

super(type[, object-or-type]):
Retourneer een proxy-object dat methodeaanroepen delegeert aan een ouder of
broer/zus klasse van type.

Dus u kuntniet doen:

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

Je moet doen:

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

Of in Python 3:

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

Antwoord 3, autoriteit 18%

Uitwerkend in het antwoord van @Oğuz Şerbetci, in python3 (niet alleen nodig in Jupyter), wanneer het nodig is om een ​​bibliotheek opnieuw te laden, we hebben bijvoorbeeld class Parenten class Childgedefinieerd als

class Parent(object):
    def __init__(self):
        # do something
class Child(Parent):
    def __init__(self):
        super(Child, self).__init__(self)

als je dit doet

import library.Child
reload(library)
Child()

u krijgt TypeError: super(type, obj): obj must be an instance or subtype of type, de oplossing is gewoon om de klasse opnieuw te importeren na het opnieuw laden

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

Antwoord 4, autoriteit 6%

Alleen voor Jupyter
Je kunt zijn probleem binnenhalen omdat de logica van reloadenkele bugs bevat (probleem)

Hier is een eenvoudige oplossing/workaround die voor mij werkt totdat het probleem niet is opgelost

  1. Voeg typefout toe zoals 1001xxonderaan het bestand dat je in de cel aanroept
  2. Laat je cel lopen – je zult een uitzondering zien, sla deze gewoon over
  3. Verwijder typfout die bij stap 1 is toegevoegd
  4. Voer de cel uit
  5. Winst

Antwoord 5, autoriteit 3%

Een andere interessante manier is als een samenvoeging van branches de klasse heeft gedupliceerd, zodat je in het bestand twee definities voor dezelfde naam hebt, bijvoorbeeld

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

Als u probeert een instantie te maken van een statische verwijzing naar de eerste definitie van A, zodra deze probeert superaan te roepen, binnen de __init__methode, Averwijst naar de tweede definitie van A, aangezien deze is overschreven. De oplossing – natuurlijk – is om de dubbele definitie van de klasse te verwijderen, zodat deze niet wordt overschreven.

Dit lijkt misschien iets dat nooit zou gebeuren, maar het overkwam me gewoon, toen ik niet goed genoeg aandacht besteedde aan het samenvoegen van twee branches. Mijn tests mislukten met de foutmelding die in de vraag wordt beschreven, dus ik dacht ik laat mijn bevindingen hier achter, ook al beantwoordt het niet precies de specifieke vraag.


Antwoord 6, autoriteit 2%

De beste oplossing die ik voor dit probleem heb gevonden, is alleen beschikbaar met python 3. Je hoeft dan de argumenten van “super” niet op te geven, dan heb je niet meer de fout om je klasse op deze manier te schrijven :

class D:
   pass
class C(D):
    def __init__(self):
        super().__init__()# no arguments given to super()

Antwoord 7

Deze fout verschijnt ook wanneer u eenvoudigweg geen onderliggende klasse instantiëert
, en probeer een methode op een klasse zelf aan te roepen, zoals in :

class Parent:
    def method():
        pass
class Child(Parent):
    def method():
        super().method()
P = Parent()
C = Child
C.method()

Other episodes