Что __init__ и self делают в Python?

Я изучаю язык программирования Python и наткнулся на то, чего не совсем понимаю.

В таком методе, как:

def method(self, blah):
    def __init__(?):
        ....
    ....

Что делает self? Что это должно быть? Это обязательно?

Что делает метод __init__? Зачем это нужно? (так далее.)

Я думаю, что это могут быть конструкции ООП, но я не очень много знаю.


person Community    schedule 09.03.2009    source источник


Ответы (17)


В этом коде:

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')) также будут переданы как аргументы - в этом случае вызывается исключение, поскольку конструктор их не ожидает.

person Chris B.    schedule 09.03.2009
comment
что, если вы поместите x = 'Hello' вне init, но внутри класса? это как Java, где это то же самое, или это становится как статическая переменная, которая инициализируется только один раз? - person Jayen; 09.04.2012
comment
Это как статическая переменная. Он инициализируется только один раз и доступен через A.x или a.x. Обратите внимание, что его переопределение в конкретном классе не повлияет на базу, поэтому A.x = 'foo'; a.x = 'bar'; print a.x; print A.x напечатает bar, затем foo - person Chris B.; 09.04.2012
comment
Стоит отметить, что первый аргумент не обязательно называть self, это просто соглашение. - person Henry Gomersall; 24.06.2012
comment
@ u449355 См. здесь stackoverflow.com/questions/4015417/ по причине использования объекта в классе A. - person Abhimanu Kumar; 11.06.2017
comment
Какой смысл object в объявлении класса? Я заметил, что в некоторых классах это есть, а в некоторых нет - person Chris; 02.12.2017
comment
@Chris Это для совместимости с Python 2. В Python 3 нет необходимости явно наследовать от object, потому что это происходит по умолчанию. - person Gabriel; 14.02.2018
comment
Я как контекст? - person Cool or Fool - SRS; 04.02.2021

Да, вы правы, это конструкции oop.

__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 (доступные в течение всего времени существования объекта).

Примечание. Некоторое разъяснение использования слова конструктор в этом ответе. Технически обязанности конструктора в Python разделены на два метода. Эти методы __new__ (отвечают за выделение памяти) и __init__ (как обсуждается здесь, отвечают за инициализацию вновь созданного экземпляра).

person RedBlueThing    schedule 09.03.2009
comment
Итак, есть ли причина, по которой вы не хотите, чтобы self был в конструкторе? Зачем вообще его указывать, не лучше ли было бы неявно? - person Aaron Franke; 07.03.2019
comment
Насколько мне известно, __ init __ не является конструктором, это первый метод, который будет выполняться при создании любого объекта, __ init __ используется для настройки объекта. __ new __ - это конструктор в Python. - person Deepanshu; 21.11.2019
comment
Для тех, кто читает этот ответ, это совершенно неверно. __init__ не выделяет место в памяти. Ожидается инициализация атрибутов экземпляра. В памяти выделяется __new__. - person black; 04.05.2021
comment
@black Фактически это текст ответа. Метод init вызывается, когда для объекта выделяется память. Он не говорит, что init выделяет память, он говорит, что он вызывается, когда выделяется память. Возможно, стоит уточнить, изменив, когда на после :) - person RedBlueThing; 05.05.2021

Краткий наглядный пример

В надежде, что это может немного помочь, вот простой пример, который я использовал, чтобы понять разницу между переменной, объявленной внутри класса, и переменной, объявленной внутри функции __init__:

class MyClass(object):
    i = 123
    def __init__(self):
        self.i = 345
     
a = MyClass()
print(a.i)
print(MyClass.i)

Выход:

345
123
person Dave Everitt    schedule 23.06.2013
comment
Интересное наблюдение, но я думаю, что вы ошиблись. С print MyClass.i это больше похоже на то, что вы вызываете «статическую» переменную i. Если, как и в случае с a.i, вы вызываете переменную-член, i. Мне кажется, что init - это просто конструктор, который сначала выполняется, когда вы создаете объект класса. - person captainspi; 23.06.2013
comment
Это то, что я пытался «объяснить себе» с помощью этого примера - что переменная, установленная __init__ - это то, что передается экземплярам класса, а не «статическая» переменная самого класса, который имеет одно и то же имя ... - person Dave Everitt; 25.06.2013

Суммируя:

  1. self, как предполагается, относится к самому - объекту, который вызвал метод. То есть, если у вас есть N объектов, вызывающих метод, тогда self.a будет ссылаться на отдельный экземпляр переменной для каждого из N объектов. Представьте N копий переменной a для каждого объекта.
  2. __init__ - это то, что называется конструктором в других языках ООП, таких как C ++ / Java. Основная идея заключается в том, что это специальный метод, который автоматически вызывается при создании объекта этого класса.
person Community    schedule 09.03.2009

Объекты класса поддерживают два типа операций: ссылки на атрибуты и создание экземпляров.

Ссылки на атрибуты используют стандартный синтаксис, используемый для всех ссылок на атрибуты в 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 :)
person Harvey    schedule 01.05.2018

__init__ действует как конструктор. Вам нужно будет передать «self» любым функциям класса в качестве первого аргумента, если вы хотите, чтобы они вели себя как нестатические методы. «self» - это переменные экземпляра для вашего класса.

person ewalk    schedule 09.03.2009
comment
'self' определяет, является ли метод статическим или нет! Вау, это откровение для этого java-парня. - person liwevire; 18.04.2018

Попробуйте этот код. Надеюсь, это поможет многим программистам на C, таким как я, выучить 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

person Jayzcode    schedule 10.05.2013
comment
Не знаю, только ли я, но чтение этого кода немного сбивало с толку. Может быть, это потому, что я все еще начинающий программист на Python, иди. - person Linny; 23.07.2018
comment
Я не совсем понимаю, что такое документация ... тянет ли он документацию? и если я сделаю: '' 'test - my doc' '', могу ли я использовать: print.p .__ test__? или документ - это конкретное ключевое слово? - person Thomas; 27.09.2018
comment
@Thomas doc - ключевое слово для документированных подробностей. Тройные кавычки используются для записи документов, а документ не является обязательным. - person Jayzcode; 18.06.2019

У меня были проблемы с пониманием этого. Даже прочитав здесь ответы.

Чтобы правильно понять метод __init__, вам нужно понять себя.

Самостоятельный параметр

Аргументы, принимаемые методом __init__:

def __init__(self, arg1, arg2):

Но на самом деле мы передаем ему только два аргумента:

instance = OurClass('arg1', 'arg2')

Откуда появился лишний аргумент?

Когда мы получаем доступ к атрибутам объекта, мы делаем это по имени (или по ссылке). Здесь instance - это ссылка на наш новый объект. Мы получаем доступ к методу printargs объекта экземпляра, используя instance.printargs.

Чтобы получить доступ к атрибутам объекта из метода __init__, нам нужна ссылка на объект.

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

Это означает, что в методе __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#the-init-method

person eee    schedule 09.01.2014

обратите внимание, что self на самом деле может быть любым допустимым идентификатором Python. Например, мы могли бы так же легко написать из примера Криса Б.

class A(object):
    def __init__(foo):
        foo.x = 'Hello'

    def method_a(bar, foo):
        print bar.x + ' ' + foo

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

person SingleNegationElimination    schedule 09.03.2009
comment
Я согласен, что self будет рекомендован вместо foo, помогает другим программистам смотреть на код - person Linny; 23.07.2018

Что делает сам? Что это означает? Это обязательно?

Первый аргумент каждого метода класса, включая init, всегда является ссылкой на текущий экземпляр класса. По соглашению этот аргумент всегда называется self. В методе инициализации self относится к вновь созданному объекту; в других методах класса он относится к экземпляру, метод которого был вызван.

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

TypeError: __init___() takes no arguments (1 given)

Что делает метод init? Зачем это нужно? (так далее.)

init - это сокращение от инициализации. Это конструктор, который вызывается, когда вы создаете экземпляр класса, и в этом нет необходимости. Но обычно мы пишем метод инициализации для установки состояния объекта по умолчанию. Если вы не хотите изначально устанавливать какое-либо состояние объекта, вам не нужно писать этот метод.

person Muhammad Faizan Khan    schedule 21.10.2017

  1. __init__ - это, по сути, функция, которая будет "инициализировать" / "активировать" свойства класса для определенного объекта, после создания и сопоставления с соответствующий класс ..
  2. self представляет тот объект, который унаследует эти свойства.
person loxsat    schedule 03.09.2015
comment
ключевое слово self использовать не обязательно, это просто заполнитель. Вы можете использовать любое слово, но рекомендуется использовать self, чтобы облегчить читаемость программы. - person Linny; 23.07.2018

По сути, вам нужно использовать ключевое слово self при использовании переменной в нескольких функциях одного класса. Что касается init, он используется для установки значений по умолчанию, если никакие другие функции из этого класса не вызываются.

person user1675111    schedule 23.09.2012
comment
В Python нет ключевого слова self. Вызов первого параметра self - это просто соглашение. - person David Anderson; 14.11.2014
comment
self используется в основном как заполнитель. Необязательно, чтобы вы использовали self, вы можете использовать eeee или foo или что-то еще, это просто рекомендуется другим программистам при чтении вашего кода - person Linny; 23.07.2018

Просто демонстрация вопроса.

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
person debug    schedule 19.04.2018

"Я" - это ссылка на экземпляр класса.

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"
person tarn    schedule 09.03.2009
comment
Почему это говорит о гибкости языка? Он просто говорит, что вы можете давать переменным любое допустимое имя по вашему выбору. Чем это отличается от любого другого языка программирования? - person Daniel; 12.09.2014
comment
Как я уже писал в своей панели ответов, это просто функция, в которой экземпляр класса предоставляется в качестве первого параметра. Итак, хотя bar определяется как метод, привязанный к foo, он также может вызываться с экземпляром некоторого другого класса. Это не то, как методы и это работают, например, в Java, хотя я полагаю, вы видите, что это одна и та же концепция, функции и некоторый контекст экземпляра (контекст экземпляра является первым параметром в Python, а это в Java). Возможно, теперь вы видите гибкость языка, о котором я говорил? - person tarn; 16.10.2014
comment
Да, это показывает гибкость языка. Судя по тому, как вы сформулировали свой ответ, казалось, что вы говорите, что тот факт, что вы можете назвать самопеременную чем-то еще (например, s), показывает гибкость python. - person Daniel; 19.10.2014

В этом коде:

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
person Anagha    schedule 25.08.2015

Здесь парень написал довольно хорошо и просто: https://www.jeffknupp.com/blog/2014/06/18/improve-your-python-python-classes-and-object-oriated-программирование/

Прочтите ссылку выше как ссылку на это:

self? Так что же с этим параметром self для всех методов Customer? Что это? Да это же экземпляр, конечно! Другими словами, такой метод, как снятие, определяет инструкции по снятию денег со счета некоторого абстрактного клиента. Вызов jeff.withdraw (100.0) помещает эти инструкции в экземпляр jeff.

Поэтому, когда мы говорим def removew (self, amount) :, мы говорим: «Вот как вы снимаете деньги с объекта Customer (который мы назовем self) и суммы в долларах (которую мы назовем суммой). Self - это экземпляр клиента, который вызывает вывод средств. Я тоже не собираюсь проводить аналогии. 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 = balance совпадает с jeff.balance = 1000.0. После этих двух строк мы считаем объект Customer "инициализированным" и готовым к использованию.

Будьте осторожны в своих __init__

После завершения init вызывающий может предположить, что объект готов к использованию. То есть, после того, как jeff = Customer ('Jeff Knupp', 1000.0), мы можем начать делать депозит и снимать звонки на jeff; jeff - полностью инициализированный объект.

person Laxmikant    schedule 13.08.2015

Python __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. Он вызывается сразу после создания экземпляра (обычно через __new__ - хотя __new__ не требуется, если вы не создаете подкласс неизменяемого типа данных).

person Aaron Hall    schedule 25.10.2017