Подтвердить что ты не робот

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__... Кто-нибудь знает почему? Это ошибка в интерпретаторе?

4b9b3361

Ответ 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 неизменяемы.