Подтвердить что ты не робот

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(). Проблема сохраняется в этих случаях.

Спасибо!

4b9b3361

Ответ 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.