Python中的子类和内置方法
为了方便,我想要创建一个ICMP套接字,所以想要对socket
进行子类化:
class ICMPSocket(socket.socket):
def __init__(self):
socket.socket.__init__(
self,
socket.AF_INET,
socket.SOCK_RAW,
socket.getprotobyname("icmp"))
def sendto(self, data, host):
socket.socket.sendto(self, data, (host, 1))
但是,我无法重写socket.sendto
这个方法:
>>> s = icmp.ICMPSocket()
>>> s.sendto
<built-in method sendto of _socket.socket object at 0x100587f00>
这是因为sendto
是一个“内置方法”。根据数据模型参考,这实际上是“一个内置函数的不同表现形式,这次包含了一个作为隐式额外参数传递给C函数的对象。”
我的问题是:在子类化时,有没有办法重写内置方法?
[编辑] 第二个问题:如果没有,为什么不可以?
2 个回答
3
重新编辑:我之前的解决方案没有奏效,经过一段时间的挣扎,我可以得出结论:在Python的socket编程中,使用组合比继承要好得多。不过,如果你想知道如何用继承来实现,可以看看这段代码:
import socket
class ICMPSocket(socket.socket):
def __init__(self):
self._sock = socket.socket(
socket.AF_INET,
socket.SOCK_RAW,
socket.getprotobyname("icmp"))
# Delete the methods overrited by the socket initializer to make
# possible defining our own.
for attr in socket._delegate_methods:
try:
delattr(self, attr)
except AttributeError:
pass
def sendto(self, data, flags, addr):
return self._sock.sendto(data, flags, (addr, 1))
icmp = ICMPSocket()
print icmp.sendto('PING', 0, '127.0.0.1')
6
我知道这不是在回答你的问题,但你可以把这个套接字放到一个实例变量里。这也是Nobody在评论中提到的建议。
class ICMPSocket():
def __init__(self):
self.s = socket.socket(
socket.AF_INET,
socket.SOCK_RAW,
socket.getprotobyname("icmp"))
def sendto(self, data, host):
self.s.sendto(data, (host, 1))
def __getattr__(self, attr):
return getattr(self.s, attr)