Python - 从旧式类继承
Posted
技术标签:
【中文标题】Python - 从旧式类继承【英文标题】:Python - inheriting from old-style classes 【发布时间】:2012-07-16 16:40:05 【问题描述】:我正在尝试通过 telnet 连接到实验室仪器。我想从标准库中的telnetlib
模块扩展Telnet
类,以包含特定于我们仪器的功能:
import telnetlib
class Instrument(telnetlib.Telnet):
def __init__(self, host=None, port=0, timeout=5):
super(Instrument,self).__init__(host, port, timeout)
我在这段代码中要做的就是从父类 (telnetlib.Telnet
) 继承 __init__
方法并传递标准参数,以便稍后我可以向 __init__
添加内容。这个公式在其他场合对我有用;这一次,当我尝试实例化时,它在super()
语句中给了我一个错误:
TypeError: must be type, not classobj
我查看了 telnetlib 的源代码,Telnet 似乎是一个老式类(它不是从 object
继承的) - 我想知道这是否是我的问题的根源?如果是这样,如何克服?我看过一些代码示例,其中派生类继承自超类和object
,尽管我不完全确定这是否是对与我相同的问题的回应。
完全披露:我还尝试使用telnetlib.Telnet
代替super()
,并使用from telnetlib import Telnet
和Telnet
代替super()
。在这些情况下问题仍然存在。
谢谢!
【问题讨论】:
【参考方案1】:您需要像这样调用constructor:
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)
【讨论】:
我试过了 - 它给了我错误:TypeError: unbound method __init__() must be called with Telnet instance as first argument (got str instance instead)
请显示您使用我刚刚发布的代码时遇到的确切代码和错误。因为如果你想调用旧式类的父构造函数,实际上就是这样做的。
啊,我发现了您的代码和我的代码之间的区别 - 您将 self
作为 __init__
的第一个参数。现在可以使用 - 感谢您这么快回复!您能否向我解释为什么需要将self
作为构造函数的第一个参数?我是 Python 新手。
请注意,这仍然会为您提供旧式课程。
您总是需要将 self 传递给任何方法(类和静态方法除外)。这在正常的点调用中是半自动的:你调用self.foo(a, b)
,Python 把它变成对foo(self, a, b)
的调用。但在这种情况下,您不是在对象上调用__init__
,而是在类上调用它,这意味着您必须显式添加self
。 (这在一些细节上有点不准确,但对于学习目的来说已经足够接近了。)【参考方案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
一起使用的新型类。
【讨论】:
从旧式类继承以创建新式类的方式是否安全? @ThiefMaster 我不知道有什么问题,但我从来没有生气过,所以我真的没有任何信息。您预计会有什么问题吗? 我不熟悉 Python 中的多继承。由于新式课程对我的目的没有任何好处,因此我将坚持上述 TheifMaster 的策略。不过还是谢谢! @poorsod 你认为python中的“多继承”有什么特别之处?新型类的主要优点之一是它们实际上可以正确处理多重继承。 @poorsodsuper
+ new-style classes 的重点是使这项工作可预测。答案是你会得到通过搜索__mro__
找到的第一个__init__
。以上是关于Python - 从旧式类继承的主要内容,如果未能解决你的问题,请参考以下文章