Python - наследование от классов старого стиля
Я пытаюсь подключиться через telnet к лабораторному инструменту. Я хотел бы расширить класс Telnet
из модуля telnetlib
в стандартной библиотеке, включив функции, специфичные для нашего инструмента:
import telnetlib
class Instrument(telnetlib.Telnet):
def __init__(self, host=None, port=0, timeout=5):
super(Instrument,self).__init__(host, port, timeout)
Все, что я пытаюсь сделать в этом коде, наследует метод __init__
от родительского класса (telnetlib.Telnet
) и передает стандартные аргументы, поэтому я могу добавить вещи в __init__
позже. Эта формула работала для меня в других случаях; на этот раз это дает мне ошибку в инструкции super()
, когда я пытаюсь создать экземпляр:
TypeError: must be type, not classobj
Я посмотрел исходный код telnetlib, и Telnet выглядит как класс старого стиля (он не наследуется от object
). Мне интересно, может ли это быть источником моей проблемы? Если да, то как его можно преодолеть? Я видел примеры кода, где производный класс наследует как от суперкласса, так и от object
, хотя я не совсем уверен, является ли это ответом на ту же проблему, что и я.
Полное раскрытие: я также попытался использовать telnetlib.Telnet
вместо super()
и from telnetlib import Telnet
с Telnet
вместо super()
. Проблема сохраняется в этих случаях.
Спасибо!
Ответы
Ответ 1
Вам нужно вызвать конструктор следующим образом:
telnetlib.Telnet.__init__(self, host, port, timeout)
Вам нужно добавить явный self
, поскольку telnet.Telnet.__init__
не является методом привязки, а скорее несвязанным методом, т.е. без назначенного экземпляра. Поэтому, когда вы вызываете его, вам нужно передать экземпляр явно.
>>> 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)
Ответ 2
Вы должны наследовать от object
, и вы должны поместить его после класса старого стиля, который вы пытаетесь наследовать (так что методы object
не найдены в первую очередь):
>>> 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>
Наследование объекта дает вам класс нового стиля, который работает с super
.