2016-11-16 2 views
1

Я читал о том, когда __new__() не возвращает экземпляр класса в stackoverflow Inheritance when __new__() doesn't return instance of class, и я знаю, что этот вопрос для python 3. Как Martijn Pieters заявляет, что это можно сделать с помощью name mangling и вызвать его вручную непосредственно в классе и полностью инициализировать его в классе.Наследование, когда __new __() не возвращает экземпляр класса в python 2.7.12

Я хочу попробовать его в python 2.7.12. Первый и второй подходы, которыми я могу управлять, но для третьего подхода поднимает TypeError.

Это мой код, первая попытка:

class A: 
    def __new__(cls, p1, p2): 
     self = object.__new__(cls) 
     self.p1 = p1 
     self.p2 = p2 
     return [self] 

class B(A): 
    def __new__(cls, p3): 
     self = super(B,cls).__new__(cls,1,2) 
     self[0].p3 = p3 
     return self 

Это дает мне TypeError: super() argument 1 must be type, not classobj

Вторая попытка:

class A(object): 
    def __new__(cls, p1, p2): 
     self = object.__new__(cls) 
     self.p1 = p1 
     self.p2 = p2 
     return [self] #return not instance 

class B(A): 
    def __new__(cls, p3): 
     self = super(B,cls).__new__(cls,1,2) 
     self[0].p3 = p3 
     return self 

Это дает мне TypeError: __new__() takes exactly 2 arguments (1 given).

Почему это происходит, может ли это быть реализовано в python 2.7.12 или эта техника несовместима?

+1

Ваша вторая попытка работает просто отлично для. меня. Вы забыли передать аргумент? –

+0

Другой вопрос о том, как вызвать '__init __()', когда подкласс имеет различное количество аргументов для этого метода, так как обычно '__init__' будет вызываться только * один раз *. Здесь вы ничего не делаете, это просто просто '__new__' переопределение. –

+0

Да, я забыл передать аргумент –

ответ

1

С вашей первой попытки вы проходите объект класса old-style, но super() принимает только классы нового стиля.

Вам необходимо наследовать от object, чтобы получить класс нового стиля, который вы правильно сделали во второй попытке. Вы просто забыл передать в качестве аргумента при создании экземпляра:

>>> class A(object): 
...  def __new__(cls, p1, p2): 
...   self = object.__new__(cls) 
...   self.p1 = p1 
...   self.p2 = p2 
...   return [self] 
... 
>>> class B(A): 
...  def __new__(cls, p3): 
...   self = super(B, cls).__new__(cls, 1, 2) 
...   self[0].p3 = p3 
...   return self 
... 
>>> B() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: __new__() takes exactly 2 arguments (1 given) 
>>> B(42) 
[<__main__.B object at 0x10241fa90>] 

Ваша ошибка вам сказал, что B.__new__ хотел два аргумента, но только cls был быть принят в

+0

oh i see sir, это случилось, потому что я вызываю экземпляр класса B без аргумента p3. B() возвращает «TypeError: __new __() принимает ровно 2 аргумента (1 задано)», но с B (42) даст основной объект B. Спасибо, сэр –

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