Новое поведение магии super()
было добавлено во избежание нарушения D.R.Y. (Не повторяйте себя), см. PEP 3135 . Чтобы явно указать класс, ссылаясь на него как на глобальный, также подвержены тем же проблемам перезаписи, которые вы обнаружили с помощью самого super()
:
class Foo(Bar):
def baz(self):
return super(Foo, self).baz() + 42
Spam = Foo
Foo = something_else()
Spam().baz() # liable to blow up
То же самое относится к использованию декораторов классов, где декоратор возвращает новый объект, который перепроверяет имя класса:
@class_decorator_returning_new_class
class Foo(Bar):
def baz(self):
# Now `Foo` is a *different class*
return super(Foo, self).baz() + 42
Магическая ячейка super()
__class__
уклоняется от этих проблем, предоставляя вам доступ к исходному объекту класса.
PEP был выпущен Guido, который изначально предполагал super
стать ключевым словом , а идея использования ячейки для поиска текущего класса была также его . Конечно, идея сделать это ключевым словом была частью первого черновика PEP .
Однако на самом деле сам Гвидо, который затем отступил от ключевое слово как «слишком магическое» , предлагая вместо этого текущую реализацию. Он предположил, что использование другого имени для super()
может быть проблемой :
В моем патче используется промежуточное решение: предполагается, что вам нужно
blockquote>__class__
всякий раз, когда вы используете переменную с именем'super'
. Таким образом, если вы (глобально) переименуетеsuper
вsupper
и используетеsupper
, но неsuper
, он не будет работать без аргументов (но он все равно будет работать, если вы передадите его либо__class__
, либо фактическое объект класса); если у вас есть несвязанная переменная с именемsuper
, все будет работать, но метод будет использовать несколько более медленный путь вызова, используемый для переменных ячейки.Итак, в конце концов, это был сам Гвидо что с использованием ключевого слова
super
не было правильно, и что предоставление магии__class__
ячейки было приемлемым компромиссом.Я согласен с тем, что магическое, неявное поведение реализации несколько удивительно, но
super()
является одной из самых неправильно применяемых функций на языке. Просто взгляните на все неправильныеsuper(type(self), self)
илиsuper(self.__class__, self)
вызовы, найденные в Интернете; если какой-либо из этого кода когда-либо вызывался из производного класса , у вас было бы исключение с бесконечной рекурсией . По меньшей мере упрощенный вызовsuper()
без аргументов позволяет избежать проблемы .Что касается переименованного
super_
; просто ссылку__class__
в свой метод , а также , и он снова будет работать. Ячейка создается, если вы ссылаетесь на именаsuper
или__class__
в вашем методе:>>> super_ = super >>> class A(object): ... def x(self): ... print("No flipping") ... >>> class B(A): ... def x(self): ... __class__ # just referencing it is enough ... super_().x() ... >>> B().x() No flipping
Предполагая, что каждый элемент 'values' соответствует столбцу в 'df', сделайте сравнение соответствующего столбца, элемента с Map
, Reduce
его с одним вектором logical
и получите sum
sum(Reduce("&", Map(">", df[columns], values)))
Или скопируйте «значения», чтобы получить длины, совпадающие с длинами столбцов набора данных, сделайте сравнение, получите rowSums
логического matrix
, проверьте, равный length
«столбцов» и получить sum
логического vector
sum(rowSums(df[columns] > rep(values, each = length(columns))) == length(columns))