在基类python / django

时间:2017-02-17 02:18:02

标签: python django oop

在您将其标记为重复之前,请允许我声明我了解超级工作方式,并且我已阅读这三个链接:

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核心实施中,有几个地方使用methodssuper继承的类上调用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

2 个答案:

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

然后尝试构建XY类型,看看它是怎么回事。

P.S。只是为了强调一些东西,这只是出于教育目的 - 不要使用它!真的没有必要诉诸于此而你只是让开发人员的生活变得生机勃勃。可能需要在将来解开你的代码。

<强>更新

根据上面 Josh J 的建议,LoginRequiredMixin可能不会被用作独立类,而是添加到多继承链中。在这种情况下,实现dispatch()方法并扩展object的基类可以粘贴到LoginRequiredMixin。考虑到Python如何做MRO,来自super()的{​​{1}}实际上会引用“粘合”&#39;类&#39;方法

您可以使代码行为相同:

LoginRequiredMixin

它仍然是一个糟糕的框架设计的标志(只考虑我们花了多长时间才能根据非常简单的代码找到问题的底部),只是稍微不如乱搞内置。所以,如果你有一天设计你的框架不要这样做,不管