Объяснение переменной "self" python начинающему
Я почти не осведомлен о жаргоне и концепциях ООП. Я знаю концептуально, что такое объект, и что у объектов есть методы. Я даже понимаю, что в python классы - это объекты! Это круто, я просто не знаю, что это значит. Он не нажимает на меня.
В настоящее время я пытаюсь понять несколько подробных ответов, которые, я думаю, осветят мое понимание python:
В первом ответе автор использует следующий код в качестве примера:
>>> class Bank(): # let create a bank, building ATMs
... crisis = False
... def create_atm(self) :
... while not self.crisis :
... yield "$100"
Я не сразу понимаю, что указывает self
. Это определенно симптом не понятных классов, над которыми я буду работать в какой-то момент. Чтобы уточнить, в
>>> def func():
... for i in range(3):
... print i
Я понимаю, что i
указывает на элемент в списке range(3)
, который, поскольку он находится в функции, не является глобальным. Но что означает self
"?
Ответы
Ответ 1
Сначала я попытаюсь прояснить некоторые путаницы в отношении классов и объектов. Давайте посмотрим на этот блок кода:
>>> class Bank(): # let create a bank, building ATMs
... crisis = False
... def create_atm(self) :
... while not self.crisis :
... yield "$100"
Комментарий есть немного обманчивый. Вышеприведенный код не создает банк. Он определяет, что такое банк. Банк - это свойство, которое имеет свойство crisis
и функцию create_atm
. Это то, что сказано выше.
Теперь давайте фактически создадим банк:
>>> x = Bank()
Там x
теперь банк. x
имеет свойство crisis
и функцию create_atm
. Вызов x.create_atm();
в python совпадает с вызовом Bank.create_atm(x);
, поэтому теперь self
относится к x
. Если вы добавите другой банк под названием y
, вызов y.create_atm()
будет знать, чтобы посмотреть y
значение кризиса, а не x
, поскольку в этой функции self
ссылается на y
.
self
- это просто соглашение об именах, но очень хорошо придерживаться его. По-прежнему стоит отметить, что приведенный выше код эквивалентен:
>>> class Bank(): # let create a bank, building ATMs
... crisis = False
... def create_atm(thisbank) :
... while not thisbank.crisis :
... yield "$100"
Ответ 2
Это может помочь вам подумать о синтаксисе вызова obj.method(arg1, arg2)
как чисто синтаксическом сахаре для вызова method(obj, arg1, arg2)
(кроме того, что method
просматривается с помощью типа obj
и не является глобальным).
Если вы так его рассматриваете, obj
является первым аргументом функции, которая традиционно называется self
в списке параметров. (На самом деле вы можете назвать его чем-то другим, и ваш код будет работать правильно, но другие кодеры Python будут хмуриться вам.)
Ответ 3
"self" - это объект экземпляра автоматически, переданный методу экземпляра класса при вызове, для идентификации экземпляра, который его вызвал. "self" используется для доступа к другим атрибутам или методам объекта изнутри метода. (методы в основном являются просто функциями, принадлежащими классу)
"self" не нужно использовать при вызове метода, когда у вас уже есть доступный экземпляр.
Доступ к атрибуту some_attribute изнутри метода:
class MyClass(object):
some_attribute = "hello"
def some_method(self, some_string):
print self.some_attribute + " " + some_string
Доступ к атрибуту some_attribute из существующего экземпляра:
>>> # create the instance
>>> inst = MyClass()
>>>
>>> # accessing the attribute
>>> inst.some_attribute
"hello"
>>>
>>> # calling the instance method
>>> inst.some_method("world") # In addition to "world", inst is *automatically* passed here as the first argument to "some_method".
hello world
>>>
Вот небольшой код, чтобы продемонстрировать, что сам то же, что и экземпляр:
>>> class MyClass(object):
>>> def whoami(self, inst):
>>> print self is inst
>>>
>>> local_instance = MyClass()
>>> local_instance.whoami(local_instance)
True
Как упоминалось другими, он назывался "я" по соглашению, но его можно было назвать как угодно.
Ответ 4
self
относится к текущему экземпляру Bank
. Когда вы создаете новый Bank
и вызываете create_atm
на нем, self
будет неявно передаваться python и будет ссылаться на созданный банк.
Ответ 5
Я не сразу понимаю, что указывает self
. Это определенно симптом непонятных классов, над которыми я буду работать в какой-то момент.
self
- это аргумент, переданный функции. В Python этот первый аргумент неявно является объектом, на который был вызван метод. Другими словами:
class Bar(object):
def someMethod(self):
return self.field
bar = Bar()
bar.someMethod()
Bar.someMethod(bar)
Эти две последние строки имеют эквивалентное поведение. (Если bar
не относится к объекту подкласса bar
- тогда someMethod()
может ссылаться на другой объект функции.)
Обратите внимание, что вы можете назвать "специальный" первый аргумент чем угодно - self
- это просто соглашение для методов.
Я понимаю, что i
указывает на элемент в списке range(3)
, который, поскольку он находится в функции, не является глобальным. Но что означает self
"?
Имя self
не существует в контексте этой функции. Попытка использовать его повысила бы NameError
.
Пример транскрипции:
>>> class Bar(object):
... def someMethod(self):
... return self.field
...
>>> bar = Bar()
>>> bar.field = "foo"
>>> bar.someMethod()
'foo'
>>> Bar.someMethod(bar)
'foo'
>>> def fn(i):
... return self
...
>>> fn(0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in fn
NameError: global name 'self' is not defined
Ответ 6
Одна перспектива Rubyist (Ruby - мой первый язык программирования, поэтому я извиняюсь за любые упрощенные, потенциально неправильные абстракции, которые я собираюсь использовать)
насколько я могу судить, оператор точки, например:
os.path
таково, что os
передается в path()
как его первая переменная "невидимо"
Как будто os.path
ДЕЙСТВИТЕЛЬНО:
path(os)
Если бы была цепочка маргаринов, я бы предположил, что это:
os.path.filename
Было бы похоже на это на самом деле *:
filename(path(os))
Здесь идет оскорбительная часть
Таким образом, с переменной self все, что делает, позволяет МЕТОД КЛАССА (с точки зрения Rubyist "методы экземпляра python" выглядят как методы класса...), чтобы действовать как метод экземпляра, получив экземпляр, переданный в него как его первую переменную ( через метод "скрытой" точки выше), который называется self
по соглашению. Являлся не экземпляром
c = ClassName()
c.methodname
но сам класс:
ClassName.methodname
класс будет передан, а не экземпляр.
ОК, также важно помнить, что метод __init__
называется "магия" некоторыми. Поэтому не беспокойтесь о том, что передается в генерировать новый экземпляр. Честно говоря, это, вероятно, nil
.
Ответ 7
self
относится к экземпляру класса.
Ответ 8
Причина "я" есть (по соглашению) в том, что когда среда выполнения Python видит вызов формы Object.Method(Param1, Param2), он вызывает метод с параметрами (Object, Param1, Param2). Поэтому, если вы называете этот первый параметр "я", каждый будет знать, о чем вы говорите.
Причина, по которой вы должны это сделать, является предметом другого вопроса.
Что касается метакласса, то это редко используется. Вы можете посмотреть на:
http://python-history.blogspot.com/2009/04/metaclasses-and-extension-classes-aka.html, автор оригинала и текущий доброжелательный диктатор For Life of Python объясняет, что это такое и как это получилось. У него также есть хорошая статья о возможных возможностях, но большинство людей никогда не использует ее напрямую.