Какова цель self
слова в Python? Я понимаю, что это относится к конкретному объекту, созданному из этого класса, но я не понимаю, почему его необходимо явно добавлять в каждую функцию в качестве параметра. Для иллюстрации, в Ruby я могу сделать это:
class myClass
def myFunc(name)
@name = name
end
end
Что я понимаю, довольно легко. Однако в Python мне нужно включить self
:
class myClass:
def myFunc(self, name):
self.name = name
Кто-нибудь может рассказать мне об этом? Это не то, с чем я столкнулся в своем (по общему признанию ограниченном) опыте.
@name
более интуитивным, чемself.name
? Последний, IMO, более интуитивно понятен.@foo
иself.foo
в равной степени явные, поскольку не требуется никакого неявного разрешения (например, в C ++ к членам экземпляра можно «неявно» обращаться без «явного» использования пространств имен). Единственное отличие состоит в том, что Ruby вводит новую семантику (@), а Python - нет. Стоит ли новая семантика того количества, которого избегают многословия, чисто субъективно. Тем не менее, следует отметить, что большинство современных языков предпочитают вводить понятие здесь (например, php's $ this, JS's this).Ответы:
Причина, которую вам нужно использовать,
self.
заключается в том, что Python не использует@
синтаксис для ссылки на атрибуты экземпляра. Python решил сделать методы так, чтобы экземпляр, которому принадлежит метод, передавался автоматически, но не получался автоматически: первый параметр методов - это экземпляр, к которому вызывается метод. Это делает методы полностью такими же, как функции, и оставляет фактическое имя для использования на ваше усмотрение (хотяself
это соглашение, и люди, как правило, недовольны вами, когда вы используете что-то другое.) Неself
является особенным для кода, это просто другой объект ,Python мог бы сделать что-то еще, чтобы отличить обычные имена от атрибутов - специальный синтаксис, как в Ruby, или требующий объявлений, как в C ++ и Java, или, возможно, что-то еще более отличное - но это не так. Python - все для того, чтобы сделать вещи явными, сделать очевидным, что к чему, и хотя он не делает это везде, он делает это для атрибутов экземпляра. Вот почему при назначении атрибута экземпляра необходимо знать, какой экземпляр назначить, и поэтому ему это нужно
self.
.источник
cls
относится к объекту класса, а не к объекту экземпляраcls
иself
используется обычно для методов экземпляра. Если бы я хотел, я мог бы использоватьself
для методов класса и,cls
например, методы. Я мог бы также использоватьbob
и,fnord
если мне понравилось.this
вместоself
. Есть лиself
какая-то история, о которой я не знаю в старых языках программирования?self
Пришли из конвенций Modula-3, см. Этот ответ для более подробной информации об этом выборе. (Отказ от ответственности: это мое).self
Ключевое слово (Smalltalk, 1980) предшествуетthis
ключевому слову (из C ++). См .: stackoverflow.com/questions/1079983/…Давайте возьмем простой векторный класс:
Мы хотим иметь метод, который вычисляет длину. Как бы это выглядело, если бы мы хотели определить его внутри класса?
Как это должно выглядеть, когда мы определяем его как глобальный метод / функцию?
Таким образом, вся структура остается прежней. Как я могу использовать это? Если мы на мгновение предположим, что мы не написали
length
метод для нашегоVector
класса, мы могли бы сделать это:Это работает, потому что первый параметр
length_global
, может быть повторно использован в качествеself
параметра вlength_new
. Это было бы невозможно без явногоself
.Другой способ понять необходимость явного
self
- посмотреть, где Python добавляет немного синтаксического сахара. Когда вы имейте в виду, что в основном, звонок каквнутренне преобразован в
легко увидеть, где это
self
подходит. На самом деле вы не пишете методы экземпляра в Python; вы пишете методы класса, которые должны принимать экземпляр в качестве первого параметра. И, следовательно, вам придется явно указать параметр экземпляра где-нибудь.источник
Vector.length_new = length_global
показывают, что методы экземпляра - это не только методы класса, но и просто функции, которые являются членами класса .Допустим, у вас есть класс,
ClassA
который содержит метод,methodA
определенный как:и
ObjectA
является экземпляром этого класса.Теперь, когда
ObjectA.methodA(arg1, arg2)
вызывается, Python внутренне преобразует его для вас как:self
Переменная относится к самому объекту.источник
Когда объекты создаются, сам объект передается в параметр self.
Из-за этого данные объекта привязаны к объекту. Ниже приведен пример того, как вы можете визуализировать, как могут выглядеть данные каждого объекта. Обратите внимание, как «я» заменяется именем объекта. Я не говорю, что приведенная ниже примерная диаграмма является полностью точной, но, надеюсь, она послужит цели визуализации использования себя.
Объект передается в параметр self, чтобы объект мог хранить свои собственные данные.
Хотя это может быть не совсем точно, подумайте о процессе создания экземпляра объекта следующим образом: когда объект создается, он использует класс в качестве шаблона для своих собственных данных и методов. Без передачи своего собственного имени в параметр self атрибуты и методы в классе останутся как общий шаблон и не будут ссылаться на объект (принадлежать ему). Таким образом, передавая имя объекта в параметр self, это означает, что, если 100 объектов созданы из одного класса, все они могут отслеживать свои собственные данные и методы.
Смотрите иллюстрацию ниже:
источник
Мне нравится этот пример:
источник
self
типа переменной, но и от нее. Попробуйте сделать первый пример с простым целым числом вместо списка. Результат будет совсем другим.a.foo
в первом примере, а неA.foo
? Очевидно,foo
принадлежит к классу ...a
иb
есть метки (или указатели) дляA()
(класса).a.foo
ссылается наA().foo
метод класса. Во втором примере, однако,a
становится ссылка на экземпляр изA()
, как это делаетb
. Теперь, когда они являются экземплярами вместо самого объекта класса, self позволяетfoo
методу работать с экземплярами.Я продемонстрирую с кодом, который не использует классы :
Классы - это просто способ избежать постоянной передачи этой «государственной» вещи (и других полезных вещей, таких как инициализация, композиция классов, редко используемые метаклассы и поддержка пользовательских методов для переопределения операторов).
Теперь давайте продемонстрируем приведенный выше код, используя встроенный механизм класса Python, чтобы показать, что это в основном то же самое.
[перенес мой ответ из дублированного закрытого вопроса]
источник
Следующие выдержки взяты из документации Python о себе :
Для получения дополнительной информации см. Руководство по документации Python по классам .
источник
Как и все другие причины, о которых уже говорилось, это упрощает доступ к переопределенным методам; вы можете позвонить
Class.some_method(inst)
.Пример того, где это полезно:
источник
Его использование аналогично использованию
this
ключевого слова в Java, то есть, чтобы дать ссылку на текущий объект.источник
Python не является языком, созданным для объектно-ориентированного программирования, в отличие от Java или C ++.
При вызове статического метода в Python каждый просто пишет метод с обычными аргументами внутри него.
Тем не менее, объектный метод, который требует, чтобы вы сделали переменную, которая является животным, в этом случае нуждается в аргументе self
Метод self также используется для ссылки на переменное поле в классе.
В этом случае self ссылается на переменную animalName всего класса. ПОМНИТЕ: Если у вас есть переменная в методе, self не будет работать. Эта переменная просто существует только во время работы этого метода. Для определения полей (переменных всего класса) вы должны определить их вне методов класса.
Если вы не понимаете ни слова из того, что я говорю, то Google "Объектно-ориентированное программирование". Как только вы поймете это, вам даже не нужно будет задавать этот вопрос :).
источник
staticMethod()
иobjectMethod(self)
. Я хотел бы добавить, что для того, чтобы вызвать первое, вы бы сказалиAnimal.staticMethod()
, в то время какobjectMethod()
нужен экземпляр:a = Animal(); a.objectMethod()
def getAnimalName
чтобы не забивать строку, которую вы пытаетесь вернуть, иself
ссылается на экземпляр класса, а не на любое поле внутри него.Он должен следовать дзену Python «явное лучше, чем неявное». Это действительно ссылка на ваш объект класса. Например, в Java и PHP это называется
this
.Если
user_type_name
это поле в вашей модели, вы получаете к нему доступself.user_type_name
.источник
Прежде всего, self - это условное имя, вместо него можно поставить что-нибудь другое (будучи связным).
Он относится к самому объекту, поэтому, когда вы его используете, вы объявляете, что .name и .age являются свойствами объектов Student (обратите внимание, не класса Student), которые вы собираетесь создать.
Код здесь
источник
self
является ссылкой на объект самого объекта, следовательно, они одинаковы. Методы Python не вызываются в контексте самого объекта.self
в Python может использоваться для работы с пользовательскими объектными моделями или чем-то еще.источник
Использование аргумента, условно названного
self
, не так сложно понять, так как зачем это нужно? Или о том, почему это явно упоминается? Это, я полагаю, более важный вопрос для большинства пользователей, которые ищут этот вопрос, или, если это не так, у них наверняка возникнет тот же вопрос, что и в дальнейшем изучении Python. Я рекомендую им прочитать эти пару блогов:1: использование самообъяснения
Обратите внимание, что это не ключевое слово.
2: Почему у нас это так и почему мы не можем исключить его в качестве аргумента, такого как Java, и вместо этого иметь ключевое слово
Еще я хотел бы добавить, что необязательный
self
аргумент позволяет мне объявлять статические методы внутри класса, не записываяself
.Примеры кода:
PS : это работает только в Python 3.x.
В предыдущих версиях вы должны явно добавить
@staticmethod
декоратор, иначеself
аргумент обязателен.источник
Я удивлен, что никто не воспитал Луа. Lua также использует переменную self, однако она может быть опущена, но все еще используется. C ++ делает то же самое с этим. Я не вижу смысла объявлять «себя» в каждой функции, но вы все равно должны иметь возможность использовать его так же, как вы можете использовать с lua и C ++. Для языка, который гордится своей краткостью, странно, что он требует, чтобы вы объявили переменную self.
источник
Взгляните на следующий пример, который четко объясняет цель
self
self
используется / необходим для различения экземпляровИсточник: самостоятельная переменная в Python объяснил - Pythontips
источник
Дело в том, что при разработке python альтернативы вряд ли будут работать. Python разработан, чтобы позволить методам или функциям быть определенными в контексте, где неявные
this
(а-ля Java / C ++) или явные@
(а-ля ruby) не будут работать. Давайте рассмотрим пример с явным подходом с соглашениями Python:Теперь
fubar
функция не будет работать, так как она будет предполагать, чтоself
это глобальная переменная (и в томfrob
числе). Альтернативой может быть выполнение методов с замененной глобальной областью действия (гдеself
находится объект).Неявный подход будет
Это будет означать, что
myX
это будет интерпретироваться как локальная переменная вfubar
(и вfrob
тоже время). Альтернативой здесь было бы выполнение методов с замененной локальной областью действия, которая сохраняется между вызовами, но это исключило бы возможность использования локальных переменных метода.Однако текущая ситуация хорошо работает:
здесь при вызове в качестве метода
frob
получит объект, для которого он вызывается черезself
параметр, иfubar
все еще может быть вызван с объектом в качестве параметра и работать так же ( как я думаю).C.frob
источник
В
__init__
методе self ссылается на вновь созданный объект; в других методах класса он ссылается на экземпляр, метод которого был вызван.Я, как имя, это просто соглашение , называйте его как хотите! но при его использовании, например, для удаления объекта, вы должны использовать то же имя:,
__del__(var)
гдеvar
использовалось в__init__(var,[...])
Вы должны взглянуть
cls
тоже, чтобы иметь более широкую картину . Этот пост может быть полезным.источник
self действует как текущее имя объекта или экземпляр класса.
источник
self
неизбежноБыл только вопрос должен
self
быть неявным или явным.Guido van Rossum
решил этот вопрос поговоркаself
должна остаться .Так где
self
живут?Если бы мы просто придерживались функционального программирования, нам бы это не понадобилось
self
. Как только мы входим в ООП Python, мы находимself
там.Вот типичный вариант использования
class C
использования методаm1
Эта программа выведет:
Так
self
держит адрес памяти экземпляра класса. Цель вself
том, чтобы содержать ссылку на методы экземпляра и предоставить нам явный доступ к этой ссылке.Обратите внимание, что есть три различных типа методов класса:
источник
из документов ,
предшествующий этому фрагмент,
x = MyClass()
источник
это явная ссылка на объект экземпляра класса.
источник