Я программировал на нескольких языках, таких как Java, Ruby, Haskell и Python. Мне приходится переключаться между многими языками в день из-за разных проектов, над которыми я работаю. Теперь проблема в том, что я часто забываю написать, так self
как первый параметр в определениях функций в Python - это вызов методов для одного и того же объекта.
Тем не менее, я весьма удивлен таким подходом Python. По сути, мы должны набрать больше, чтобы добиться цели, в таких языках, как Java и Ruby, все делается просто, автоматически ссылаясь на переменные в текущем объекте.
Мой вопрос: зачем это self
нужно? Это просто выбор стиля, или есть причина, почему Python не может позволить вам опустить self
то, что Java и C ++ позволяют вам опустить this
?
@staticmethod
перед объявлением метода подавляет ошибку (только для информации и также не рекомендуется)Ответы:
1) Почему
self
требуется в качестве явного параметра в сигнатурах метода?Потому что методы являются функциями и
foo.bar(baz)
просто синтаксическим сахаром дляbar(foo, baz)
. Классы - это просто словари, в которых некоторые значения являются функциями. (Конструкторы также являются просто функциями, поэтому Python не нуженnew
). Вы можете сказать, что Python явно указывает, что объекты создаются из более простых компонентов. Это в соответствии с «явным лучше, чем неявным» -философия.Напротив, в Java объекты действительно волшебны и не могут быть сведены к более простым компонентам в языке. В Java (по крайней мере, до Java 8) функция всегда является методом, принадлежащим объекту, и это владение не может быть изменено из-за статической природы языка. Поэтому нет никакой двусмысленности в отношении того, что
this
относится к этому, поэтому имеет смысл определить его неявным образом.JavaScript - это пример языка, который неявно
this
похож на Java, но где функции могут существовать отдельно от объектов, как в Python. Это приводит к большим путаницы о том , чтоthis
относится к , когда функции передаются вокруг и называются в различных контекстах. Многие инстинктивно думают, чтоthis
должны ссылаться на некоторое внутреннее свойство функции, в то время как оно на самом деле чисто определяется способом вызова функции. Я считаю, что наличиеthis
в качестве явного параметра, такого как в Python, сделает это намного менее запутанным.Некоторые другие преимущества явного
self
-параметра:Декораторы - это просто функции, которые обертывают другие функции. Поскольку методы - это просто функции, декораторы так же хорошо работают с методами. Если бы было какое-то неявное «я», декораторы не работали бы прозрачно с методами.
Методы класса и статические методы не принимают параметр экземпляра. Методы класса принимают класс в качестве первого аргумента (как правило, называется
cls
). Явныеself
илиcls
параметры делают намного более понятным, что происходит и к чему у вас есть доступ в методе.2) Почему переменные экземпляров всегда должны быть квалифицированы как "
self.
?В Java вам не нужно ставить переменные-члены перед "
this.
", но в Python "self.
" всегда требуется. Причина в том, что Python не имеет явного синтаксиса для объявления переменных, поэтому нет никакого способа узнать,x = 7
предполагается ли объявить новую локальную переменную или назначить переменную-член. Указаниеself.
решает эту двусмысленность.источник
self.
как, например, Java) принципиально несовместима с правилами области видимости, и когда вам нужно быть там явным, неявное отношение к параметру больше не имеет особого смысла.Существует довольно простая причина, по которой AFAIK на самом деле не затрагивался ни в межсайтовом дубликате, ни здесь: Python начинался как процедурный язык. Это было основано на ABC, также процедурном языке.
Объектно-ориентация была добавлена позже, и когда она была добавлена, Гвидо ван Россум хотел добавить минимально возможное количество возможностей, чтобы сделать дизайн Python простым. В Python уже есть
dict
s и функции, так зачем добавлять что-то совершенно новое в язык, когда объект может быть простоdict
из слотов, а класс может просто бытьdict
из функций? Метод можно интерпретировать как частично примененную функцию, которая закрывается по одному выделенному аргументу. И именно так методы реализуются в Python: это не так. Это просто функции, которые получают дополнительный выдающийся аргумент.источник
Вот мои выводы, основанные на приведенных выше ответах и прочтении собственного бессвязного Гвидо по этой теме:
Большая идея
Функции являются важными строительными блоками в Python (или мы должны сказать, единственный), на самом деле мы эмулируем ООП с помощью функций.
Учитывая, что класс - это не что иное, как словарь функций, следовательно, мы можем присоединить любую функцию к любому классу во время выполнения. По сути, из-за этой необходимости перебрасывать функции во время выполнения мы можем делать такие вещи, как Monkey Patching . Здесь
self
параметр, поддерживающий параметрический полиморфизм.источник