在您将其标记为重复之前,请允许我声明我了解超级工作方式,并且我已阅读这三个链接:
What does 'super' do in Python?
Understanding Python super() with __init__() methods
http://python-history.blogspot.nl/2010/06/method-resolution-order.html
super
baseclasses
的工作原理
class X(object):
def __init__(self):
print "calling init from X"
super(X, self).__init__()
class Y(object):
def abc(self):
print "calling abc from Y"
super(Y, self).abc()
a = X()
# prints "calling init from X" (works because object possibly has an __init__ method)
b = Y()
b.abc()
# prints "calling abc from Y" and then
# throws error "'super' object has no attribute 'abc'" (understandable because object doesn't have any method named abc)
问题:在django
核心实施中,有几个地方使用methods
在super
继承的类上调用object
(案例我上面的例子中Y
。例如:有人可以解释为什么这段代码有效吗?
from django.core.exceptions import PermissionDenied
class LoginRequiredMixin(object):
def dispatch(self, request, *args, **kwargs):
if not request.user.is_authenticated():
raise PermissionDenied
return super(LoginRequiredMixin, self).\
dispatch(request, *args, **kwards) # why does this work?
参考:从此演讲中复制了此代码:https://youtu.be/rMn2wC0PuXw?t=403
答案 0 :(得分:2)
它的工作原理是因为LoginRequiredMixin旨在用于多继承场景。在这种情况下,MRO将解析为类层次结构的同一级别中的对象。 (与LoginRequiredMixin一起指定的另一种类型)
您可以在下面看到订单也很重要
Python 2.7.12 (default, Oct 11 2016, 05:20:59)
[GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.38)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>>
>>> class Y(object):
... def abc(self):
... print "calling abc from Y"
... super(Y, self).abc()
...
>>> class Z(object):
... def abc(self):
... print "calling abc from Z"
...
>>> class YZ(Y, Z): # multiple inheritance
... pass
...
>>> c = YZ()
>>> c.abc()
calling abc from Y
calling abc from Z
>>>
>>> class ZY(Z,Y): pass
...
>>> ZY().abc()
calling abc from Z
ZY
根据MRO调用Z.abc
,因此Y.abc
被忽略
答案 1 :(得分:1)
您是否测试过该演示文稿中的所有代码?上面的代码可能只有在有人在幕后做一些不应该做的事情(并且在某些Python实现中被严格禁止)时才会起作用 - 修改Python内置函数。
您也可以这样做 - 在执行或构建任何内容之前,请执行以下操作:
import __builtin__
class custom_object(object):
def abc(self):
print "calling abc from custom_object"
__builtin__.object = custom_object
然后尝试构建X
和Y
类型,看看它是怎么回事。
P.S。只是为了强调一些东西,这只是出于教育目的 - 不要使用它!真的没有必要诉诸于此而你只是让开发人员的生活变得生机勃勃。可能需要在将来解开你的代码。
<强>更新强>
根据上面 Josh J 的建议,LoginRequiredMixin
可能不会被用作独立类,而是添加到多继承链中。在这种情况下,实现dispatch()
方法并扩展object
的基类可以粘贴到LoginRequiredMixin
。考虑到Python如何做MRO,来自super()
的{{1}}实际上会引用“粘合”&#39;类&#39;方法
您可以使代码行为相同:
LoginRequiredMixin
它仍然是一个糟糕的框架设计的标志(只考虑我们花了多长时间才能根据非常简单的代码找到问题的底部),只是稍微不如乱搞内置。所以,如果你有一天设计你的框架不要这样做,不管。