Python中的子类和内置方法

时间:2011-08-07 22:02:53

标签: python subclassing

为方便起见,我想将socket子类化为创建ICMP套接字:

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是“内置方法”。根据{{​​3}},这是“内置函数的一个不同的伪装,这次包含一个作为隐式额外参数传递给C函数的对象。”

我的问题:无论如何要在子类化时覆盖内置方法吗?

[编辑]第二个问题:如果没有,为什么不呢?

2 个答案:

答案 0 :(得分: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)

答案 1 :(得分:4)

重新编辑:我的第一个解决方案无法正常工作,并且经过一段时间的讨论后,我可以得出结论,在python套接字的情况下,你可以说聚合比继承,但万一你想知道如何做 它使用继承检查此代码:

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')