Mam błąd, którego nie mogę zrozumieć. Masz jakieś pojęcie, co jest nie tak z moim przykładowym kodem?
class B:
def meth(self, arg):
print arg
class C(B):
def meth(self, arg):
super(C, self).meth(arg)
print C().meth(1)
Otrzymałem przykładowy kod testowy z pomocą wbudowanej metody „super”.
Oto błąd:
Traceback (most recent call last):
File "./test.py", line 10, in ?
print C().meth(1)
File "./test.py", line 8, in meth
super(C, self).meth(arg)
TypeError: super() argument 1 must be type, not classobj
Do Twojej wiadomości, oto pomoc (super) samego Pythona:
Help on class super in module __builtin__:
class super(object)
| super(type) -> unbound super object
| super(type, obj) -> bound super object; requires isinstance(obj, type)
| super(type, type2) -> bound super object; requires issubclass(type2, type)
| Typical use to call a cooperative superclass method:
| class C(B):
| def meth(self, arg):
| super(C, self).meth(arg)
|
Odpowiedzi:
Problem polega na tym, że klasa B nie została zadeklarowana jako klasa „nowego stylu”. Zmień to tak:
i zadziała.
super()
i wszystkie elementy podklasy / superklasy działają tylko z klasami w nowym stylu. Zalecam, abyś przyzwyczaił się zawsze wpisywać to(object)
w dowolnej definicji klasy, aby mieć pewność, że jest to klasa nowego stylu.Klasy w starym stylu (znane również jako klasy „klasyczne”) są zawsze typu
classobj
; klasy w nowym stylu są typutype
. Oto dlaczego zobaczyłeś komunikat o błędzie:TypeError: super() argument 1 must be type, not classobj
Spróbuj tego, aby przekonać się sam:
Zauważ, że w Pythonie 3.x wszystkie klasy są w nowym stylu. Nadal możesz używać składni z klas starego stylu, ale otrzymujesz klasę nowego stylu. Tak więc w Pythonie 3.x nie będziesz mieć tego problemu.
źródło
super()
; klasa A musi być przystosowana do pracy z klasą „w starym stylu”, a być może najlepszym sposobem na to byłoby uczynienie klasy A samą klasą „w starym stylu”. Oczywiście polecam uaktualnienie całego programu do działania w Pythonie 3.x, aby wszystkie klasy miały nowy styl bez względu na to, co robisz; jeśli ta opcja jest dostępna, jest to najlepsza opcja.class B(object):
. Otrzymuję ten błąd z powodu użycia@mock.patch('module.B', autospec=B)
tuż przed moim przypadkiem testowym. Wszelkie przemyślenia, jak to naprawić?Ponadto, jeśli nie możesz zmienić klasy B, możesz naprawić błąd, używając wielokrotnego dziedziczenia.
źródło
type
), a jednocześnie podklasuje klasę „starego stylu” (której obiekt klasy jest typuclassobj
).super()
działa z klasami w nowym stylu, ale nie z klasami w starym stylu.Jeśli wersja Pythona to 3.X, jest w porządku.
Myślę, że twoja wersja Pythona to 2.X, super działałoby podczas dodawania tego kodu
więc kod jest
źródło
Wystąpił również problem z opublikowanym problemem, gdy korzystałem z Pythona 2.7. Działa bardzo dobrze z Pythonem 3.4
Aby działał w Pythonie 2.7, dodałem
__metaclass__ = type
atrybut u góry mojego programu i działał.__metaclass__
: Ułatwia przejście z klas w starym stylu do klas w nowym stylu.źródło