2012-01-24 2 views
59

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

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

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


>>> s=test() 
init 2 

Наконец, Есть __init__ оператор overloader?

+22

Технически, '__init__' является * инициализатором *. Конструктор python * - '__new__'. Python использует автоматическую двухфазную инициализацию - '__new__' возвращает действительный, но (обычно) непосещенный объект (см.' Bool' для встречного примера), который затем '__init__' вызывал его автоматически. Это позволяет избежать проблем с такими языками, как C++, с частично сконструированными объектами - в Python у вас их никогда не было (хотя оно может быть частично инициализировано). Вам почти никогда не придется переопределять как '__new__', так и' __init__' в классе. –

+2

@TimDelaney: Я не уверен, что вы имеете в виду с частично построенными объектами в C++. –

+7

@phresnel В C++ тип объекта - это базовый класс (а не подкласс), а в конструкторе базового класса. Вы не можете вызвать виртуальный метод в конструкторе базового класса и предоставить подкласс для реализации. В Java вы можете вызвать метод подкласса в конструкторе базового класса, но переменные-члены подкласса автоматически инициализируются * после * конструктора базового класса (и вызова метода). В языках с двухфазной инициализацией, такой как Python, вы можете с радостью вызывать методы в инициализаторе базового класса и иметь подкласс, обеспечивающий (или переопределяющий) поведение. –

ответ

76

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

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

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

+0

Это также означает, что исходный файл последовательно анализируется (интерпретируется?)? Могу ли я быть уверенным, что какая-либо функция, которую я определил позже, перезаписывает тот, который был определен тем же именем ранее? :(мой Q звучит глупо .. должен был знать это – 0xc0de

+4

@ 0xc0de: В Python определения функций на самом деле являются * исполняемыми операторами * и выполняются сверху вниз, поэтому да. – NPE

+0

Спасибо, человек ....... Это объясняет output –

7

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

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

>>> 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 ...

+0

Это было очень четкое объяснение ... Спасибо, человек ...... –

+0

Нет проблем, рад, что это вам помогло:) –

1

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

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 

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

46

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

Потому что __init__ строит ваш объект.

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

Как указано в official documentation__init__ является вызывается при создании экземпляра, другие методы не получают это лечение.

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

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

Например 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 

«Я» - это стандартное слово, используемое как первый аргумент функции метода, это первый аргумент - экземпляр объекта (за исключением class/static-способами), в нашем случае t.

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

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

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

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

+0

Это очистило много концепций ....... Спасибо, сэр –

0

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

Смежные вопросы