Что __init__ и self делают на Python? - PullRequest
674 голосов
/ 09 марта 2009

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

В методе, подобном:

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

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

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

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

Ответы [ 18 ]

518 голосов
/ 09 марта 2009

В этом коде:

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

216 голосов
/ 09 марта 2009

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

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

169 голосов
/ 23 июня 2013

Краткий иллюстративный пример

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

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

a = MyClass()
print a.i
345
print MyClass.i
123
38 голосов
/ 09 марта 2009

Короче говоря:

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

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

25 голосов
/ 09 марта 2009

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

21 голосов
/ 10 января 2014

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

Чтобы правильно понять метод __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#the-init-method

16 голосов
/ 09 марта 2009

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

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

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

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

16 голосов
/ 01 мая 2018

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

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

Операция instantiation («вызов» объекта класса) создает пустой объект. Многие классы любят создавать объекты с экземплярами, настроенными на конкретное начальное состояние. Поэтому класс может определять специальный метод с именем __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 :)
14 голосов
/ 04 сентября 2015
  1. __init__ - это, в основном, функция, которая "инициализирует" / "активирует" свойства класса для определенного объекта, после создания и соответствует соответствующему классу ..
  2. self представляет тот объект, который унаследует эти свойства.
...