Различие, которое рисует автор, состоит в том, что для языка Python у вас есть действительный объект указанного типа до , в который вы даже вводите __init__
.Следовательно, это не «конструктор», поскольку в C ++ и теоретически конструктор превращает недопустимый предварительно созданный объект в «правильный» завершенный объект типа.
В основном __new__
в Python определен каквернуть «экземпляр нового объекта», тогда как новые операторы C ++ просто возвращают некоторую память, которая еще не является экземпляром какого-либо класса.
Однако, __init__
в Python, вероятно, - то, где вы сначала устанавливаете некоторые важные инварианты класса(какие атрибуты у него есть, только для начала).Таким образом, что касается пользователей вашего класса, он также может быть конструктором.Просто среда выполнения Python не заботится ни об одном из этих инвариантов.Если хотите, у него очень низкие стандарты того, что составляет построенный объект.
Я думаю, что автор делает справедливое замечание, и это, безусловно, интересное замечание о том, как Python создает объекты.Это довольно тонкое различие, и я сомневаюсь, что вызов __init__
конструктора когда-либо приведет к некорректному коду.
Также отмечу, что документация Python ссылается на __init__
как конструктор (http://docs.python.org/release/2.5.2/ref/customization.html)
Как специальное ограничение для конструкторов, никакое значение не может быть возвращено
... поэтому, если есть практические проблемы с представлением __init__
как конструктора, тогда Pythonв беде!
То, как объекты Python и C ++ имеют некоторые сходства, вызывает функцию с относительно простой ответственностью (__new__
для экземпляра объекта против некоторой версии operator new
для необработанной памяти),затем оба вызывают функцию, которая имеет возможность проделать дополнительную работу для инициализации объекта в полезное состояние (__init__
по сравнению с конструктором).
Практические различия включают в себя:
в C ++, конструкторы без аргументов для базовых классов при необходимости вызываются автоматически в соответствующем порядке, тогда как для __init__
в Python вы должныявно инициируйте свою базу в своем собственном __init__
.Даже в C ++ вы должны указать конструктор базового класса, если он имеет аргументы.
в C ++, у вас есть целый механизм для того, что происходит, когда конструктор выдает исключение, с точки зрениявызов деструкторов для уже созданных подобъектов.Я думаю, что в Python среда выполнения (самое большее) вызывает __del__
.
Кроме того, есть разница, что __new__
не просто выделяет память, этодолжен вернуть фактический экземпляр объекта.Опять же, необработанная память не является концепцией, которая применима к коду Python.