супер и __new__ путаница - PullRequest
       10

супер и __new__ путаница

26 голосов
/ 19 сентября 2011

Как я только что узнал, я могу использовать super() следующим образом:
super(class, obj_of_class-or-_subclass_of_class)

Код идет ниже:

#Case 1
class A(object):
    def __init__(self):
        print "A init"

class B(A):
    def __init__(self):
        print "B init"
        super(B, self).__init__()  #ok, I can invoke A's __init__ successfully

#Case 2
class A(object):
    @classmethod
    def foo(cls):
        print "A foo"

class B(object):
    @classmethod
    def foo(cls):
        print "B foo"
        super(B, cls).foo()   #ok, I can invoke A's foo successfully

#Case 3
class A(object):
    def __new__(cls):
      print "A new"
      return super(A, cls).__new__(cls)

class B(A):
    def __new__(cls):
      print "B new"
      return super(B, cls).__new__()  #Oops, error

ВОПРОС:

В случаях 1 и 2 я могу успешно использовать super без указания obj или cls для работы. Но почему я не могу сделать то же самое для __new__? Потому что в случае 3, если я использую супер таким образом, я получил ошибку. Но если я использую это так:

super(B, cls).__new__(cls)

Нет ошибок.

1 Ответ

33 голосов
/ 19 сентября 2011

Из примечаний к выпуску Python о переопределении метода __new__:

__new__ является статическим методом , а не методом класса.Сначала я думал, что это должен быть метод класса, и поэтому я добавил примитив classmethod.К сожалению, с методами класса upcalls не работают правильно в этом случае, поэтому мне пришлось сделать его статическим методом с явным классом в качестве первого аргумента.

Поскольку __new__ является статическим методом, super(...).__new__ возвращает статический метод.В этом случае нет привязки cls к первому аргументу.Все аргументы должны быть указаны явно.

...