Подтвердить что ты не робот

Конструкторы Python и __init__

Почему конструкторы действительно называются "конструкторы"? Какова их цель и как они отличаются от методов в классе?

Кроме того, может быть больше одного __init__ в классе? Я попробовал что-то вроде следующего: может кто-нибудь объяснить результат?

>>> class test:
    def __init__(self):
        print "init 1"
    def __init__(self):
        print "init 2"


>>> s=test()
init 2

Наконец, Is __init__ оператор-перегрузчик?

4b9b3361

Ответ 1

В Python нет перегрузки функций, что означает, что вы не можете иметь несколько функций с одним и тем же именем, но с разными аргументами.

В вашем примере кода вы не перегружаете __init__(). Случается так, что второе определение связывает имя __init__ с новым методом, делая первый метод недоступным.

Что касается вашего общего вопроса о конструкторах, Википедия - хорошая отправная точка. Для Python-специфичных вещей, я настоятельно рекомендую документы по Python.

Ответ 2

Почему конструкторы действительно называются "Конструкторами"?

Конструктор (с именем __new__) создает и возвращает новый экземпляр класса. Таким образом, метод класса C.__new__ является конструктором для класса C.

C.__init__ экземпляра C.__init__ вызывается для конкретного экземпляра после его создания, чтобы инициализировать его перед передачей вызывающей стороне. Так что этот метод является инициализатором для новых экземпляров C.

Чем они отличаются от методов в классе?

Как указано в официальной документации, __init__ вызывается после создания экземпляра. Другие методы не получают этого лечения.

Какова их цель?

Целью конструктора C.__new__ является определение пользовательского поведения при создании нового экземпляра C

Цель инициализатора C.__init__ - определить пользовательскую инициализацию каждого экземпляра C после его создания.

Например, Python позволяет вам делать:

class Test(object):
    pass

t = Test()

t.x = 10   # here you're building your object t
print t.x

Но если вы хотите, чтобы каждый экземпляр Test имел атрибут x равный 10, вы можете поместить этот код в __init__:

class Test(object):
    def __init__(self):
        self.x = 10

t = Test()
print t.x

Каждый метод экземпляра (метод, вызываемый для определенного экземпляра класса) получает экземпляр в качестве первого аргумента. Этот аргумент условно называется self

Методы класса, такие как конструктор __new__, вместо этого получают класс в качестве первого аргумента.

Теперь, если вам нужны пользовательские значения для атрибута x все, что вам нужно сделать, это передать это значение в качестве аргумента __init__:

class Test(object):
    def __init__(self, x):
        self.x = x

t = Test(10)
print t.x
z = Test(20)
print t.x

Я надеюсь, что это поможет вам устранить некоторые сомнения, и, поскольку вы уже получили хорошие ответы на другие вопросы, я остановлюсь здесь :)

Ответ 3

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

Для них обычно используются переменные для этого объекта:

>>> class testing:
...     def __init__(self, init_value):
...         self.some_value = init_value

Итак, что вы можете сделать, это создать объект из этого класса следующим образом:

>>> testobject = testing(5)

Тогда тестовый объект будет иметь объект с именем some_value, который в этом примере будет равен 5.

>>> testobject.some_value
5

Но вам не нужно устанавливать значение для каждого объекта, как в моем примере. Вы также можете сделать следующее:

>>> class testing:
...     def __init__(self):
...         self.some_value = 5

тогда значение some_value будет равно 5, и вам не нужно будет устанавливать его при создании объекта.

>>> testobject = testing()
>>> testobject.some_value
5

→ > и... в моем примере это не то, что вы пишете. Как это выглядело бы в pyshell...

Ответ 4

Конструкторы

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

def func(): #now func refers to an empty funcion
    pass
...
func=5      #now func refers to the number 5
def func():
    print "something"    #now func refers to a different function

в определении вашего класса, он просто сохраняет более поздний

Ответ 5

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