简体   繁体   English

Python中的子类和内置方法

[英]Subclassing and built-in methods in Python

For convenience, I wanted to subclass socket to create an ICMP socket: 为方便起见,我想继承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))

However, I can't override socket.sendto : 但是,我无法覆盖socket.sendto

>>> s = icmp.ICMPSocket()
>>> s.sendto
<built-in method sendto of _socket.socket object at 0x100587f00>

This is because sendto is a "built-in method". 这是因为sendto是一种“内置方法”。 According to the data model reference , this is "really a different disguise of a built-in function, this time containing an object passed to the C function as an implicit extra argument." 根据数据模型引用 ,这“实际上是内置函数的不同伪装,这次包含作为隐式额外参数传递给C函数的对象。”

My question: is there anyway to override built-in methods when subclassing? 我的问题:无论如何都要在子类化时覆盖内置方法?

[Edit] Second question: if not, why not? [编辑]第二个问题:如果没有,为什么不呢?

I know this doesn't answer your question, but you could put the socket into an instance variable. 我知道这不能解答您的问题,但您可以将套接字放入实例变量中。 This is what Nobody also suggested in the comments. 这是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)

Re-edit : My first solution wasn't working, and after straggling with this for sometime , i can conclude that in the case of python socket when you can say that aggregation is much better than inheriting but in case you want to know how you can do it using inheritance check this code: 重新编辑 :我的第一个解决方案无法正常工作,并且经过一段时间的讨论后,我可以得出结论,在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')

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM