2017-02-17 5 views
1

Перед тем, как пометить его как дубликат, позвольте мне сказать, что я понимаю, как супер работает, и я прочитал эти три ссылки:вызова супер на базовый класс питона/Джанго

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? 

Ref: скопировал этот код из этого разговора: https://youtu.be/rMn2wC0PuXw?t=403

ответ

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. Чтобы подчеркнуть что-то, это представлено только в образовательных целях - НЕ ИСПОЛЬЗУЙТЕ ЭТО! На самом деле нет необходимости когда-либо прибегать к этому, и вы просто сделаете жизнь живым ад для разработчиков, которым может понадобиться распутать ваш код в будущем.

ОБНОВЛЕНИЕ:

Согласно предложению выше Джош J «с, LoginRequiredMixin не может быть предназначен для использования в качестве автономного класса, но добавил в цепи множественного наследования. В этом случае базовый класс, который реализует метод dispatch() и распространяется object, может быть приклеен к LoginRequiredMixin. Принимая во внимание, как Python делает MRO, super() от LoginRequiredMixin фактически ссылается на методы «склеенных» классов.

Вы можете получить свой код, чтобы вести себя так же, как:

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() 
# prints "calling abc from Y" and then 
# prints "calling abc from Z" 

Он по-прежнему является признаком плохого каркаса (только подумайте, как долго он взял нас, чтобы добраться до нижней части вопроса на основе весьма простой код), чуть менее жестокий, чем возиться со встроенными. Итак, если вы проектируете свою инфраструктуру один день НЕ ДЕЛАЙТЕ ЭТО, А.

+0

Спасибо за ваш ответ. То, что вы говорите, имеет какой-то смысл, но я серьезно сомневаюсь, что «джанго» это делает. Если бы это было так, им пришлось бы реализовать много таких 'abc' .. Кроме того, я не мог найти ничего подобного в' django' github repo –

+1

Вы правы, разработчики Django - хорошие мальчики. Я извиняюсь перед тем, кого я мог обидеть, подразумевая, что они возились со встроенными людьми. Код в презентации либо не работает, либо тот, кто сделал презентацию, запутанную со встроенными. – zwer

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 звонки Z.abc на основе MRO так Y.abc игнорируется

+0

Я не уверен, понимаю ли я. Из этой реализации, как вы можете сказать, что она выполняет множественное наследование? И если да, то какой второй класс он наследует? –

+1

@ TheWanderer - если вы должны что-то делать, например 'Class YourClass (LoginRequiredMixin, MixinWithDispatch)', и если 'MixinWithDispatch' расширяет' object' и имеет 'dispatch()' метод, этот 'супер' вызов из' LoginRequiredMixin' будет разрешать на 'MixinWithAbc.dispatch()'. Если бы вы использовали 'LoginRequiredMixin' в одиночку, это сломалось бы, как ожидалось, если вы не возились со встроенными. И да, полагаясь на множественное наследование и MRO, также является признаком плохой структуры дизайна - не столько, сколько с изменением встроенных функций, но на самом деле нет никаких оснований делать это так. – zwer

+0

@zwer это очень хороший ответ. Спасибо. Можете ли вы отредактировать свой ответ с этим, чтобы я мог отметить его как разрешенный? –

 Смежные вопросы

  • Нет связанных вопросов^_^