Вопрос-Ответ

What is the purpose of the `self` parameter? Why is it needed?

Для чего нужен параметр `self`? Зачем он нужен?

Рассмотрим этот пример:

class MyClass:
def func(self, name):
self.name = name

Я знаю, что self относится к конкретному экземпляру MyClass. Но почему он должен func явно включать self в качестве параметра? Зачем нам нужно использовать self в коде метода? Некоторые другие языки делают это неявным или используют вместо этого специальный синтаксис.


Для независимого от языка рассмотрения проектного решения см. В чем преимущество обязательного указания указателя this / self?.

Чтобы закрыть вопросы отладки, где OP опустил self параметр для метода и получил TypeError, используйте TypeError: method() принимает 1 позиционный аргумент, но вместо него было задано 2. Если OP опущен self. в теле метода и получил NameError, подумайте , как я могу вызвать функцию внутри класса?.

Переведено автоматически
Ответ 1

Причина, по которой вам нужно использовать self., заключается в том, что Python не использует специальный синтаксис для обращения к атрибутам экземпляра. Python решил создать методы таким образом, чтобы экземпляр, которому принадлежит метод, был передан автоматически, но не был получен автоматически: первый параметр методов - это экземпляр, для которого вызывается метод. Это делает методы полностью такими же, как функции, и оставляет фактическое имя для использования на ваше усмотрение (хотя self это соглашение, и люди обычно будут хмуриться, когда вы используете что-то другое.) self не является чем-то особенным для кода, это просто еще один объект.

Python мог бы сделать что-то еще, чтобы отличать обычные имена от атрибутов - специальный синтаксис, как у Ruby, или требующий объявлений, как у C ++ и Java, или, возможно, что-то еще более отличное - но этого не произошло. Python предназначен для того, чтобы делать вещи явными, делая очевидным, что к чему, и хотя он не делает это полностью везде, он делает это, например, для атрибутов. Вот почему при назначении атрибута экземпляра необходимо знать, какому экземпляру присваивать, и вот почему это необходимо self..

Ответ 2

Допустим, у вас есть класс, ClassA который содержит метод, methodA определенный как:

class ClassA:
def methodA(self, arg1, arg2):
... # do something

и objectA является экземпляром этого класса.

Теперь при вызове objectA.methodA(arg1, arg2) python внутренне преобразует его для вас в виде:

ClassA.methodA(objectA, arg1, arg2)

self Переменная ссылается на сам объект.

Ответ 3

Давайте возьмем простой векторный класс:

class Vector:
def __init__(self, x, y):
self.x = x
self.y = y

Мы хотим иметь метод, который вычисляет длину. Как бы это выглядело, если бы мы захотели определить его внутри класса?

    def length(self):
return math.sqrt(self.x ** 2 + self.y ** 2)

Как это должно выглядеть, когда мы должны были определить его как глобальный метод / функцию?

def length_global(vector):
return math.sqrt(vector.x ** 2 + vector.y ** 2)

Таким образом, вся структура остается прежней. Как я могу это использовать? Если мы предположим на мгновение, что мы не написали length метод для нашего Vector класса, мы могли бы сделать это:

Vector.length_new = length_global
v = Vector(3, 4)
print(v.length_new()) # 5.0

Это работает, потому что первый параметр length_global, может быть повторно использован в качестве self параметра в length_new. Это было бы невозможно без явного self .


Другой способ понять необходимость явного self - посмотреть, где Python добавляет некоторый синтаксический сахар. Если иметь в виду, что в основном вызов типа

v_instance.length()

внутренне преобразуется в

Vector.length(v_instance)

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

Ответ 4

При создании экземпляров объектов сам объект передается в self параметр.

введите описание изображения здесь

Из-за этого данные объекта привязываются к объекту. Ниже приведен пример того, как можно было бы визуализировать, как могли бы выглядеть данные каждого объекта. Обратите внимание, как self заменяется именем объекта. Я не говорю, что приведенный ниже пример диаграммы полностью точен, но, надеюсь, он поможет визуализировать использование self.

введите описание изображения здесь

Объект передается в self параметр, чтобы объект мог сохранять свои собственные данные.

Хотя это может быть не совсем точно, представьте себе процесс создания экземпляра (и присвоения внутренних значений) объекта следующим образом: при создании объекта объект использует класс в качестве шаблона для своих (объекта) собственных данных и методов. Без передачи собственного имени переменной объекта в self параметр атрибуты и методы в классе оставались бы общим шаблоном и не ссылались бы на объект (не принадлежали бы ему). Итак, передавая имя объекта в self параметр, это означает, что если 100 объектов создаются из одного класса, каждый из 100 объектов может отслеживать свои (каждого объекта) собственные данные и методы.

Краткое описание: Классы - это общие (не сверхспецифичные) шаблоны, в которые вновь созданный объект может передавать свои собственные специфические данные (без обязательного влияния на остальные объекты, которые могли бы быть созданы из того же класса), что позволяет использовать меньше копируемого кода, который служит для создания множества объектов с одинаковыми шаблонами. self предназначен для указания, что данные определенного объекта должны использоваться вместо каких-либо других данных.

Смотрите иллюстрацию ниже:

введите описание изображения здесь

python class