Python: расширение int и MRO для __init__
В Python я пытаюсь расширить встроенный тип int. При этом я хочу передать некоторые аргументы keywoard конструктору, поэтому я делаю это:
class C(int):
def __init__(self, val, **kwargs):
super(C, self).__init__(val)
# Do something with kwargs here...
Однако при вызове C(3)
работает отлично, C(3, a=4)
дает:
'a' is an invalid keyword argument for this function`
и C.__mro__
возвращает ожидаемое:
(<class '__main__.C'>, <type 'int'>, <type 'object'>)
Но кажется, что Python пытается сначала называть int.__init__
... Кто-нибудь знает почему? Это ошибка в интерпретаторе?
Ответы
Ответ 1
Документы для модели данных Python советуют использовать __new__
:
объект. новый (cls [,...])
new() предназначен главным образом для того, чтобы подклассы неизменяемых типов (например, int, str или кортеж) настраивали создание экземпляра. Он также обычно переопределяется в пользовательских метаклассах, чтобы настроить создание классов.
Что-то вроде этого должно сделать это для примера, который вы дали:
class C(int):
def __new__(cls, val, **kwargs):
inst = super(C, cls).__new__(cls, val)
inst.a = kwargs.get('a', 0)
return inst
Ответ 2
Вы должны переопределить
"__new__"
, а не "__init__"
, поскольку ints неизменяемы.
Ответ 3
Что все остальные (пока) сказали. Int неизменяемы, поэтому вам нужно использовать новый.
Также см. (принятые ответы):