Используя супер с методом класса

document.getElementById('leaveCode').value = '10';

, Который должен установить выбор на "Ежегодный Отпуск"

68
задан unutbu 12 June 2018 в 00:16
поделиться

4 ответа

Sometimes texts have to be read more for the flavor of the idea rather than for the details. This is one of those cases.

In the linked page, Examples 2.5, 2.6 and 2.7 should all use one method, do_your_stuff. (That is, do_something should be changed to do_your_stuff.)

In addition, as Ned Deily pointed out, A.do_your_stuff has to be a class method.

class A(object):
    @classmethod
    def do_your_stuff(cls):
        print 'This is A'

class B(A):
    @classmethod
    def do_your_stuff(cls):
        super(B, cls).do_your_stuff()

B.do_your_stuff()

super(B, cls).do_your_stuff возвращает метод bound (см. сноску 2 ). Поскольку cls было передано в качестве второго аргумента super () , именно cls привязывается к возвращаемому методу. Другими словами, cls передается в качестве первого аргумента методу do_your_stuff () класса A.

Повторим: super (B, cls) .do_your_stuff () вызывает метод A do_your_stuff вызывается с cls , переданным в качестве первого аргумента. Чтобы это работало, A do_your_stuff должен быть методом класса. На связанной странице это не упоминается, but that is definitively the case.

PS. do_something = classmethod(do_something) is the old way of making a classmethod. The new(er) way is to use the @classmethod decorator.


Note that super(B, cls) can not be replaced by super(cls, cls). Doing so could lead to infinite loops. For example,

class A(object):
    @classmethod
    def do_your_stuff(cls):
        print('This is A')

class B(A):
    @classmethod
    def do_your_stuff(cls):
        print('This is B')
        # super(B, cls).do_your_stuff()  # CORRECT
        super(cls, cls).do_your_stuff()  # WRONG

class C(B):
    @classmethod
    def do_your_stuff(cls):
        print('This is C')
        # super(C, cls).do_your_stuff()  # CORRECT
        super(cls, cls).do_your_stuff()  # WRONG

C.do_your_stuff()

will raise RuntimeError: maximum recursion depth exceeded while calling a Python object.

If cls is C, then super(cls, cls) searches C.mro() for the class that comes after C.

In [161]: C.mro()
Out[161]: [__main__.C, __main__.B, __main__.A, object]

Since that class is B, when cls is C, super(cls, cls).do_your_stuff() always calls B.do_your_stuff. Since super(cls, cls).do_your_stuff() is called inside B.do_your_stuff, you end up calling B.do_your_stuff in an infinite loop.

In Python3, the 0-argument form of super was added so super(B, cls) could be replaced by super(), and Python3 will figure out from context that super() in the definition of class B should be equivalent to super(B, cls).

But in no circumstance is super(cls, cls) (or for similar reasons, super(type(self), self)) ever correct.

83
ответ дан 24 November 2019 в 14:18
поделиться

Пример с веб-страницы, похоже, работает как опубликованный. Вы также создали метод do_something для суперкласса, но не превратили его в метод класса? Что-то вроде этого даст вам эту ошибку:

>>> class A(object):
...     def do_something(cls):
...         print cls
... #   do_something = classmethod(do_something)
... 
>>> class B(A):
...     def do_something(cls):
...         super(B, cls).do_something()
...     do_something = classmethod(do_something)
... 
>>> B().do_something()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in do_something
TypeError: unbound method do_something() must be called with B instance as first argument (got nothing instead)
2
ответ дан 24 November 2019 в 14:18
поделиться

Думаю, теперь я понял суть дела благодаря этому прекрасному сайту и прекрасному сообществу.

Если вы не возражаете, поправьте меня, если я ошибаюсь в методах классов (которые я сейчас пытаюсь понять полностью):


# EXAMPLE #1
>>> class A(object):
...     def foo(cls):
...             print cls
...     foo = classmethod(foo)
... 
>>> a = A()
>>> a.foo()
# THIS IS THE CLASS ITSELF (__class__)
class '__main__.A'

# EXAMPLE #2
# SAME AS ABOVE (With new @decorator)
>>> class A(object):
...     @classmethod
...     def foo(cls):
...             print cls
... 
>>> a = A()
>>> a.foo()
class '__main__.A'

# EXAMPLE #3
>>> class B(object):
...     def foo(self):
...             print self
... 
>>> b = B()
>>> b.foo()
# THIS IS THE INSTANCE WITH ADDRESS (self)
__main__.B object at 0xb747a8ec
>>>

Я надеюсь, что эта иллюстрация показывает ..

0
ответ дан 24 November 2019 в 14:18
поделиться

Я обновил статью, чтобы сделать ее немного понятнее: Атрибуты и методы Python # Super

В приведенном выше примере с использованием метода класса показано, что такое метод класса - он передает сам класс вместо экземпляра в качестве первого параметра. Но вам даже не нужен экземпляр для вызова метода, например:

>>> class A(object):
...     @classmethod
...     def foo(cls):
...         print cls
... 
>>> A.foo() # note this is called directly on the class
<class '__main__.A'>
3
ответ дан 24 November 2019 в 14:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: