Конструкторы Python и __init__ - PullRequest
94 голосов
/ 24 января 2012

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

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

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


>>> s=test()
init 2

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

Ответы [ 5 ]

107 голосов
/ 24 января 2012

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

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

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

62 голосов
/ 24 января 2012

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

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

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

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

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

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

Цель конструктора C.__new__ - определить пользовательское поведение при создании нового C instance.

Цель инициализатора 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

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

9 голосов
/ 24 января 2012

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

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

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

1 голос
/ 24 января 2012

coonstructors вызывается автоматически при создании нового объекта, тем самым «конструируя» объект. Причина, по которой вы можете иметь более одного 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

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

0 голосов
/ 24 января 2012

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...