2012-07-17 16 views
26

Próbuję połączyć się za pomocą telnetu z instrumentem laboratoryjnym. Chciałbym rozszerzyć klasę Telnet z modułu telnetlib w bibliotece standardowej, w celu włączenia funkcji specyficznych dla naszego instrumentu:Python - dziedzicząc z klas w starym stylu

import telnetlib 
class Instrument(telnetlib.Telnet): 
    def __init__(self, host=None, port=0, timeout=5): 
     super(Instrument,self).__init__(host, port, timeout) 

Wszystko staram się zrobić w tym kodzie jest dziedziczą metodę z rodzicem __init__ klasa (telnetlib.Telnet) i przekazuj standardowe argumenty, więc mogę później dodać rzeczy do __init__. Ta formuła przydała mi się przy innych okazjach; Tym razem to daje mi błąd w rachunku super() gdy próbuję instancję:

TypeError: must be type, not classobj 

Spojrzałem na kodzie źródłowym telnetlib i Telnet wydaje się klasę w starym stylu (nie dziedziczą object) - Zastanawiam się, czy to może być źródłem mojego problemu? Jeśli tak, jak można go pokonać? Widziałem kilka przykładów kodu, w których klasa pochodna dziedziczy zarówno z nadklasy i object, choć nie jestem całkowicie pewien, czy jest to odpowiedź na ten sam problem, co ja.

Pełne ujawnienie: Próbowałem również używając telnetlib.Telnet zamiast super() i from telnetlib import Telnet z Telnet zamiast super(). Problem występuje w tych przypadkach.

Dzięki!

Odpowiedz

36

Trzeba wezwać constructor takiego:

telnetlib.Telnet.__init__(self, host, port, timeout) 

Trzeba dodać wyraźne self od telnet.Telnet.__init__ nie jest granica metoda ale raczej niezwiązany metoda, tj witout instancji przypisanej. Dlatego podczas wywoływania tego musisz wyraźnie przekazać instancję.

>>> Test.__init__ 
<unbound method Test.__init__> 
>>> Test().__init__ 
<bound method Test.__init__ of <__main__.Test instance at 0x7fb54c984e18>> 
>>> Test.__init__() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: unbound method __init__() must be called with Test instance as first argument (got nothing instead) 
+0

Próbowałem tego - daje mi błąd: 'TypeError: niezwiązana metoda __init __() musi być wywołana z instancją Telnet jako pierwszym argumentem (zamiast tego otrzymała instancję str)' –

+0

Pokaż dokładny kod i błąd, który otrzymujesz kod, który właśnie wysłałem. Ponieważ tak właśnie jest, jeśli chcesz wywołać konstruktora macierzystego klasy w starym stylu. – ThiefMaster

+0

Ach, zauważyłem różnicę między twoim kodem a moim - miałeś "self" jako pierwszy argument '__init__'. Działa teraz - dzięki za szybką odpowiedź! Czy byłbyś w stanie wyjaśnić mi, dlaczego musisz podać "self" jako pierwszy argument konstruktora? Jestem nowy w Pythonie. –

13

Trzeba dziedziczą object i należy go umieścić po klasie starym stylu, który próbujesz dziedziczyć (tak, że metody object „s nie znaleziono pierwsze):

>>> class Instrument(telnetlib.Telnet,object): 
...  def __init__(self, host=None, port=0, timeout=5): 
...   super(Instrument,self).__init__(host, port, timeout) 
... 
>>> Instrument() 
<__main__.Instrument object at 0x0000000001FECA90> 

Dziedziczenie z obiektu daje klasę nowego stylu, która działa z super.

+2

Czy można bezpiecznie odziedziczyć po klasie w starym stylu w sposób, który na tej podstawie tworzy klasę nowego stylu? – ThiefMaster

+0

@ ThiefMaster Nie jestem świadomy żadnych problemów, ale nigdy nie robiłem tego w gniewie, więc naprawdę nie mam żadnych informacji. Czy spodziewasz się problemów? – Marcin

+0

Nie jestem zaznajomiony z dziedziczeniem wielokrotnym w języku Python. Ponieważ klasa w nowym stylu nie przynosi żadnych korzyści dla mojego celu, zamierzam trzymać się powyższej strategii TheifMaster. Mimo to dzięki! –

Powiązane problemy