object.__init__() takes exactly one argument (the instance to initialize)
Интереса ради решил поиграться с классами и заметил такую интересную штуку. Допустим, я хочу создать класс, который будет являться datetime.datetime с одним дополнительным атрибутом:
import datetime
class Foo(datetime.datetime):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) # Вызываем конструктор родителя
self.foo = 5 # Добавляем свой атрибут
При попытке создать экземпляр класса с параметрами:
f = Foo(2020, 1, 1)
Получаю ошибку:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-2-6b5ccf5358aa> in <module>
----> 1 f = Foo(2020, 1, 1)
<ipython-input-1-31281291039f> in __init__(self, *args, **kwargs)
4 class Foo(datetime.datetime):
5 def __init__(self, *args, **kwargs):
----> 6 super().__init__(*args, **kwargs) # Вызываем конструктор родителя
7 self.foo = 5 # Добавляем свой атрибут
8
TypeError: object.__init__() takes exactly one argument (the instance to initialize)
Из-за чего ошибка и как добиться того, что я хочу?
Код целиком для копипаста:
import datetime
class Foo(datetime.datetime):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) # Вызываем конструктор родителя
self.foo = 5 # Добавляем свой атрибут
f = Foo(2020, 1, 1)
Ответы (1 шт):
В библиотеке datetime используется несколько непривычный метод конструирования объекта (который иногда встречается в модулях стандартной библиотеки). А именно, инициализация аттрибутов объекта происходит в методе __new__, __init__ же в свою очередь не переопределяется (определен в object), поэтому его вызов не нужен.
В вашем случае явный вызов метода __init__ родителя по дереву наследования приводит к вызову object.__init__().
Без вызова конструктора родителя:
import datetime
class Foo(datetime.datetime):
def __init__(self, *args, **kwargs):
self.foo = 5 # Добавляем свой атрибут
f = Foo(2020, 1, 1)
print(f, f.foo, sep='\n')
# 2020-01-01 00:00:00
# 5