Python __init__ и self что они делают?
Я изучаю язык программирования Python и натолкнулся на то, что не до конца понимаю.
В методе, как:
def method(self, blah):
def __init__(?):
....
....
Что значит self
делать? Что это значит? Это обязательно?
Что это __init__
метод сделать? Зачем это нужно? (так далее.)
Я думаю, что они могут быть ООП-конструкциями, но я не очень много знаю.
18 ответов
В этом коде:
class A(object):
def __init__(self):
self.x = 'Hello'
def method_a(self, foo):
print self.x + ' ' + foo
... self
Переменная представляет экземпляр самого объекта. Большинство объектно-ориентированных языков передают это как скрытый параметр методам, определенным для объекта; Python нет. Вы должны объявить это явно. Когда вы создаете экземпляр A
класс и вызовите его методы, он будет передан автоматически, как в...
a = A() # We do not pass any argument to the __init__ method
a.method_a('Sailor!') # We only pass a single argument
__init__
Метод примерно то, что представляет конструктор в Python. Когда вы звоните A()
Python создает объект для вас и передает его в качестве первого параметра __init__
метод. Любые дополнительные параметры (например, A(24, 'Hello')
) также будет передан в качестве аргументов - в этом случае вызывается исключение, так как конструктор их не ожидает.
Да, вы правы, это неоправданные конструкции.
__init__
является конструктором для класса. self
Параметр относится к экземпляру объекта (например, this
в C++).
class Point:
def __init__(self, x, y):
self._x = x
self._y = y
__init__
Метод вызывается при выделении памяти для объекта:
x = Point(1,2)
Важно использовать self
параметр внутри метода объекта, если вы хотите сохранить значение в объекте. Если, например, вы реализуете __init__
метод как это:
class Point:
def __init__(self, x, y):
_x = x
_y = y
Ваш x
а также y
параметры будут храниться в переменных в стеке и будут отброшены, когда метод init выходит из области видимости. Установка этих переменных как self._x
а также self._y
устанавливает эти переменные в качестве членов Point
объект (доступный для жизни объекта).
Краткий иллюстративный пример
В надежде, что это немного поможет, вот простой пример, который я использовал, чтобы понять разницу между переменной, объявленной внутри класса, и переменной, объявленной внутри __init__
функция:
class MyClass(object):
i = 123
def __init__(self):
self.i = 345
a = MyClass()
print a.i
345
print MyClass.i
123
Короче:
self
как это предполагает, относится к себе- объект, который вызвал метод. То есть, если у вас есть N объектов, вызывающих метод, тоself.a
будет ссылаться на отдельный экземпляр переменной для каждого из N объектов. Представьте себе N копий переменнойa
для каждого объекта__init__
это то, что называется конструктором в других языках ООП, таких как C++/Java. Основная идея заключается в том, что это специальный метод, который автоматически вызывается при создании объекта этого класса.
Объекты класса поддерживают два вида операций: ссылки на атрибуты и создание экземпляров.
Ссылки на атрибуты используют стандартный синтаксис, используемый для всех ссылок на атрибуты в Python: obj.name. Допустимые имена атрибутов - это все имена, которые были в пространстве имен класса при создании объекта класса. Итак, если определение класса выглядело так:
class MyClass:
"""A simple example class"""
i = 12345
def f(self):
return 'hello world'
затем MyClass.i
а также MyClass.f
являются действительными ссылками на атрибуты, возвращая целое число и объект функции, соответственно. Атрибуты класса также могут быть назначены, так что вы можете изменить значение MyClass.i
по назначению. __doc__
также является допустимым атрибутом, возвращающим строку документации, принадлежащую классу: "Простой пример класса".
Реализация класса использует функцию обозначения. Просто представьте, что объект класса является функцией без параметров, которая возвращает новый экземпляр класса. Например:
x = MyClass()
Операция создания экземпляра ("вызов" объекта класса) создает пустой объект. Многие классы любят создавать объекты с экземплярами, настроенными на конкретное начальное состояние. Поэтому класс может определять специальный метод с именем __init__()
, как это:
def __init__(self):
self.data = []
Когда класс определяет __init__()
метод, экземпляр класса автоматически вызывает __init__()
для вновь созданного экземпляра класса. Таким образом, в этом примере новый инициализированный экземпляр может быть получен с помощью:
x = MyClass()
Конечно, __init__()
Метод может иметь аргументы для большей гибкости. В этом случае аргументы, переданные оператору создания класса, передаются __init__()
, Например,
class Complex:
def __init__(self, realpart, imagpart):
self.r = realpart
self.i = imagpart
x = Complex(3.0, -4.5)
x.r, x.i
Взято из официальной документации, которая мне больше всего помогла в итоге.
Вот мой пример
class Bill():
def __init__(self,apples,figs,dates):
self.apples = apples
self.figs = figs
self.dates = dates
self.bill = apples + figs + dates
print ("Buy",self.apples,"apples", self.figs,"figs
and",self.dates,"dates.
Total fruitty bill is",self.bill," pieces of fruit :)")
Когда вы создаете экземпляр класса Bill:
purchase = Bill(5,6,7)
Ты получаешь:
> Buy 5 apples 6 figs and 7 dates. Total fruitty bill is 18 pieces of
> fruit :)
__init__
действует как конструктор. Вам нужно будет передать "self" любым функциям класса в качестве первого аргумента, если вы хотите, чтобы они вели себя как нестатические методы. "self" - это переменные экземпляра для вашего класса.
Попробуйте этот код. Надеюсь, что это поможет многим программистам на Си, таким как я, освоить Py.
#! /usr/bin/python2
class Person:
'''Doc - Inside Class '''
def __init__(self, name):
'''Doc - __init__ Constructor'''
self.n_name = name
def show(self, n1, n2):
'''Doc - Inside Show'''
print self.n_name
print 'Sum = ', (n1 + n2)
def __del__(self):
print 'Destructor Deleting object - ', self.n_name
p=Person('Jay')
p.show(2, 3)
print p.__doc__
print p.__init__.__doc__
print p.show.__doc__
Выход:
Jay
Sum = 5
Doc - Inside Class
Doc - __init__ Constructor
Doc - Inside Show
Destructor Deleting object - Jay
У меня были проблемы с пониманием этого. Даже после прочтения ответов здесь.
Чтобы правильно понять __init__
метод, который вы должны понять сам.
Параметр собственной личности
Аргументы, принятые __init__
метод являются:
def __init__(self, arg1, arg2):
Но мы только фактически передаем ему два аргумента:
instance = OurClass('arg1', 'arg2')
Откуда взялись дополнительные аргументы?
Когда мы получаем доступ к атрибутам объекта, мы делаем это по имени (или по ссылке). Здесь экземпляр является ссылкой на наш новый объект. Мы обращаемся к методу printargs объекта instance, используя instance.printargs.
Для доступа к атрибутам объекта изнутри __init__
Метод, нам нужна ссылка на объект.
Всякий раз, когда вызывается метод, в качестве первого аргумента передается ссылка на главный объект. По соглашению вы всегда вызываете этот первый аргумент для своих методов self.
Это означает, что в __init__
метод, который мы можем сделать:
self.arg1 = arg1
self.arg2 = arg2
Здесь мы устанавливаем атрибуты для объекта. Вы можете проверить это, выполнив следующие действия:
instance = OurClass('arg1', 'arg2')
print instance.arg1
arg1
такие значения известны как атрибуты объекта. Здесь __init__
Метод устанавливает атрибуты arg1 и arg2 экземпляра.
источник: http://www.voidspace.org.uk/python/articles/OOP.shtml
Обратите внимание, что self
на самом деле может быть любой действительный идентификатор Python. Например, мы могли бы так же легко написать на примере Криса Б.
class A(object):
def __init__(foo):
foo.x = 'Hello'
def method_a(bar, foo):
print bar.x + ' ' + foo
и это будет работать точно так же. Однако рекомендуется использовать self, потому что другие питонеры распознают его легче.
Что делает сам? Что это значит? Это обязательно?
Первый аргумент каждого метода класса, включая init, всегда является ссылкой на текущий экземпляр класса. По соглашению этот аргумент всегда называется self. В методе init self ссылается на вновь созданный объект; в других методах класса это относится к экземпляру, метод которого был вызван.
Python не заставляет вас использовать "себя". Вы можете дать ему любое имя. Но помните, что первый аргумент в определении метода - это ссылка на объект.Python добавляет аргумент self в список для вас; вам не нужно включать его при вызове методов. если вы не указали self в методе init, вы получите ошибку
TypeError: __init___() takes no arguments (1 given)
Что делает метод init? Зачем это нужно? (так далее.)
init, короткий для инициализации. Это конструктор, который вызывается, когда вы создаете экземпляр класса, и в этом нет необходимости. Но обычно мы пишем метод init для установки состояния объекта по умолчанию. Если вы не желаете изначально устанавливать какое-либо состояние объекта, вам не нужно писать этот метод.
__init__
в основном это функция, которая будет "инициализировать" / "активировать" свойства класса для конкретного объекта, после того как он создан и сопоставлен с соответствующим классом.self
представляет тот объект, который будет наследовать эти свойства.
По сути, вам нужно использовать ключевое слово "self" при использовании переменной в нескольких функциях в одном классе. Что касается init, он используется для установки значений по умолчанию, если никакие другие функции из этого класса не вызываются.
"Я" является ссылкой на экземпляр класса
class foo:
def bar(self):
print "hi"
Теперь мы можем создать экземпляр foo и вызвать для него метод, в этом случае Python добавляет параметр self:
f = foo()
f.bar()
Но это также может быть передано, если вызов метода не в контексте экземпляра класса, код ниже делает то же самое
f = foo()
foo.bar(f)
Интересно, что имя переменной "self" - это просто соглашение. Приведенное ниже определение будет работать точно так же. Сказав, что это очень строгое соглашение, которому следует всегда следовать, но оно действительно говорит о гибкой природе языка.
class foo:
def bar(s):
print "hi"
Просто демо на вопрос.
class MyClass:
def __init__(self):
print('__init__ is the constructor for a class')
def __del__(self):
print('__del__ is the destructor for a class')
def __enter__(self):
print('__enter__ is for context manager')
return self
def __exit__(self, exc_type, exc_value, traceback):
print('__exit__ is for context manager')
def greeting(self):
print('hello python')
if __name__ == '__main__':
with MyClass() as mycls:
mycls.greeting()
$ python3 class.objects_instantiation.py
__init__ is the constructor for a class
__enter__ is for context manager
hello python
__exit__ is for context manager
__del__ is the destructor for a class
В этом коде:
class Cat:
def __init__(self, name):
self.name = name
def info(self):
print 'I am a cat and I am called', self.name
Вот __init__
действует как конструктор для класса, и когда создается объект, вызывается эта функция. self
представляет экземпляр объекта.
c = Cat('Kitty')
c.info()
Результат приведенных выше заявлений будет следующим:
I am a cat and I am called Kitty
Вы были бы правы, они являются объектно-ориентированными конструкциями. В принципе self
является ссылкой (вроде как указатель, но self
это специальная ссылка, которую вы не можете назначить) на объект, и __init__
это функция, которая вызывается для инициализации объекта, то есть для установки значений переменных и т. д., сразу после выделения памяти для него.
# Source: Class and Instance Variables
# https://docs.python.org/2/tutorial/classes.html#class-and-instance-variables
class MyClass(object):
# class variable
my_CLS_var = 10
# sets "init'ial" state to objects/instances, use self argument
def __init__(self):
# self usage => instance variable (per object)
self.my_OBJ_var = 15
# also possible, class name is used => init class variable
MyClass.my_CLS_var = 20
def run_example_func():
# PRINTS 10 (class variable)
print MyClass.my_CLS_var
# executes __init__ for obj1 instance
# NOTE: __init__ changes class variable above
obj1 = MyClass()
# PRINTS 15 (instance variable)
print obj1.my_OBJ_var
# PRINTS 20 (class variable, changed value)
print MyClass.my_CLS_var
run_example_func()
питон
__init__
а такжеself
что они делают?Что значит
self
делать? Что это значит? Это обязательно?Что это
__init__
метод сделать? Зачем это нужно? (так далее.)
Приведенный пример неверен, поэтому позвольте мне создать правильный пример на его основе:
class SomeObject(object):
def __init__(self, blah):
self.blah = blah
def method(self):
return self.blah
Когда мы создаем экземпляр объекта, __init__
вызывается для настройки объекта после его создания. То есть когда мы звоним SomeObject
с 'blah'
ниже (что может быть что угодно), он передается __init__
функция в качестве аргумента, blah
:
an_object = SomeObject('blah')
self
аргумент является примером SomeObject
который будет назначен an_object
,
Позже мы можем захотеть вызвать метод для этого объекта:
an_object.method()
Делаем точечный поиск, то есть an_object.method
, привязывает экземпляр к экземпляру функции, и метод (как было вызвано выше) теперь является "связанным" методом - это означает, что нам не нужно явно передавать экземпляр в вызов метода.
Вызов метода получает экземпляр, поскольку он был связан с точечным поиском, а при вызове выполняет любой код, который был запрограммирован для выполнения.
Неявно прошло self
аргумент называется self
условно. Мы могли бы использовать любое другое допустимое имя Python, но другие программисты Python, скорее всего, получат смолу и перья, если вы измените его на что-то другое.
__init__
это специальный метод, описанный в документации по Python datamodel. Он вызывается сразу после создания экземпляра (обычно через __new__
- хотя __new__
не требуется, если вы не наследуете неизменяемый тип данных).
Здесь парень написал довольно хорошо и просто: https://www.jeffknupp.com/blog/2014/06/18/improve-your-python-python-classes-and-object-oriented-programming/
Прочитайте ссылку выше как ссылку на это:
self
? Так что же с этим параметром self для всех методов Customer? Что это? Да ведь это, конечно, случай! Другими словами, метод, как снять, определяет инструкции для снятия денег с некоторого абстрактного счета клиента. Вызов jeff.withdraw(100.0) помещает эти инструкции для использования в экземпляр jeff.Таким образом, когда мы говорим, что def изъять (self, amount):, мы говорим: "вот как вы снимаете деньги с объекта Customer (который мы назовем self) и цифру в долларах (которую мы назовем sum). это тот случай, когда вызывается запрос клиента, и я тоже не подхожу к аналогиям. jeff.withdraw(100.0) - это просто сокращение для Customer.withdraw(jeff, 100.0), которое совершенно правильно (если его не часто видели) код.
init self может иметь смысл для других методов, но как насчет init? Когда мы вызываем init, мы находимся в процессе создания объекта, так как же может существовать самость? Python позволяет нам расширять сам шаблон, когда объекты также создаются, даже если он не совсем подходит. Просто представьте, что jeff = Customer('Jeff Knupp', 1000.0) - это то же самое, что вызов jeff = Customer(jeff, 'Jeff Knupp', 1000.0); Джефф, который был передан, также является результатом.
Вот почему, когда мы вызываем init, мы инициализируем объекты, говоря что-то вроде self.name = name. Помните, поскольку self является экземпляром, это эквивалентно произнесению jeff.name = name, которое совпадает с jeff.name = 'Jeff Knupp. Аналогично, self.balance = баланс такой же, как jeff.balance = 1000.0. После этих двух строк мы считаем объект Customer "инициализированным" и готовым к использованию.
Будь осторожен с тем, что ты
__init__
После завершения init вызывающая сторона может правильно предположить, что объект готов к использованию. То есть после того, как jeff = Customer('Jeff Knupp', 1000.0), мы можем начать вносить и снимать вызовы на jeff; Джефф - полностью инициализированный объект.
def __init__(self):
На самом деле это похоже на конструктор по умолчанию (например, в java или других языках программирования высокого уровня. Фактически он используется для инициализации элементов в конструкторе по умолчанию и
def is as usual here similar to creating a method here it is a constructor hence in order to initialise few variables at the object initiation call of the class itself and self
как
this
оператор для доступа / ссылки на собственный объект класса, например:
class helloworld:
def __init__(self):
self.value='hello world'
print(value)
objofhelloworld=helloworld()