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
super(type, obj): obj must be an instance or subtype of type
提问by Chaklader Asfak Arefe
I work on a small Django
app and get an error tells me, super(type, obj): obj must be an instance or subtype of type
. I get it from the views.py
file after introducing the function get_object_or_404
. The views.py
file 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 18
in the models.py
is qs_main = super(URL, self).all(*args, **kwargs)
and the models.py
file is here,
该line 18
中models.py
是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'
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 super
using the UrlManager
class as first argument not the URL
model. super
cannot 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 Parent
and class Child
defined as
在@O?uz ?erbetci 的回答中详细说明,在 python3 中(仅在 Jupyter 中不需要),当需要重新加载库时,例如我们有class Parent
并class 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, A
will 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 reload
logic have some bugs (issue)
仅适用于 Jupyter您可以解决他的问题,因为reload
逻辑有一些错误(问题)
Here is a simple solution/workaround that works for me until issue is not fixed
这是一个简单的解决方案/解决方法,在问题未解决之前对我有用
- Add typo like
1001xx
at the bottom of the file which you call in the cell - Run your cell - you will see some exception, just skip it
- Remove typo which was added on step 1
- Run the cell
- Profit
1001xx
在您在单元格中调用的文件底部添加错字- 运行你的单元格 - 你会看到一些异常,跳过它
- 删除在步骤 1 中添加的错字
- 运行单元格
- 利润