2015-01-30 3 views
2

Там есть класс (не создана мной, из 3-сторонней библиотеки), которая не имеет __init__ объявленную (кроме object «s __init__), и это его __new__:Python подклассов класса с обычаем __new__

def __new__(cls, uid): 
    self = super().__new__(cls, uid) 
    self._info = get_info_from_uid(uid) 
    return self 

Не понимаю, почему они просто не использовали __init__ здесь, но они этого не сделали.

Теперь я хотел бы подклассифицировать это и дать ему дополнительный атрибут; прежде чем я проверил исходный код класса (только документация), я думал, что это просто использует __init__ как другие, так вот что я сделал:

class MyClass(TheirClass): 
    def __init__(self, uid, my_stuff=()): 
     super().__init__(uid) 
     self.my_stuff = my_stuff 

Видимо, поднял TypeError от object.__init__() не принимающих parameteres. Как я должен подклассифицировать такой класс с помощью __new__? Я просто переопределяю метод __new__?

+0

В '__new__' метод, как и опубликовано, не будет работать, если класс не наследует от чего-то другого, кроме самого объекта; 'object .__ new__' не принимает аргументов в этом случае. Я ожидаю, что он прочитает 'self = super() .__ new __ (cls)'. –

+0

Также, конечно, они бы использовали 'get_info_from_uid (uid)' (а не 'self.uid')? –

+0

@MartijnPieters Да, он наследует и от нескольких других классов, но у них также нет '__init__'. И жаль насчет 'self.uid', это была моя опечатка при попытке создать свой собственный класс, забыли его там. –

ответ

5

Поскольку первоначальный проект застрял с __new__ и использованием как __init__ и __new__ вместе в подклассах can get very tricky indeed, вы должны будете использовать __new__ в подклассах, а также:

class MyClass(TheirClass): 
    def __new__(cls, uid, my_stuff=()): 
     self = super().__new__(cls, uid) 
     self.my_stuff = my_stuff 
     return self 

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

Вы все еще можете использовать __init__ если вы настаиваете, но вы должны будете указать __new__ метод в любом случае для учета дополнительного аргумента ваш __init__ теперь принимает:

class MyClass(TheirClass): 
    def __new__(cls, uid, *args): 
     # ignore the extra arguments 
     return super().__new__(cls, uid) 

    def __init__(self, uid, my_stuff=()): 
     self.my_stuff = my_stuff 
+0

«Возможно, оригинальный автор считал, что этот тип следует рассматривать как непреложный». Можете ли вы немного рассказать об этом? Как '__new__' связано с тем, чтобы сделать объект неизменным? Edit: Да, спасибо, я просто переопределяю '__new__' в моем подклассе! :) –

 Смежные вопросы

  • Нет связанных вопросов^_^