python classmethod在调用时会抱怨

时间:2016-01-29 20:35:03

标签: python autobahn

我有一个classmethod:

class MyServerProtocol(WebSocketServerProtocol):

    @classmethod
    def send(cls, text):
        cls.sendMessage(cls, text)

    def onMessage(self, payload, isBinary):
        msp=MyServerProtocol
        msp.send('test')

我正在尝试调用这个类方法(现在作为测试,来自课堂内),我得到了:

exceptions.TypeError: unbound method sendMessage() must be called with MyServerProtocol instance as first argument (got type instance instead)

期待一个实例并抱怨它有一个实例......任何人都知道如何正确地调用它。一旦我开始工作,我可以在另一个类中进行测试,只是想在迁移之前先让它工作。

编辑:

我修改了我的代码以调用方法如下,但现在仍在使用。

class MyServerProtocol(WebSocketServerProtocol):

    def onMessage(self, payload, isBinary):

        myInput = literal_eval(payload)
        cg = coreg.DataGatherCg()
        cg.test(myInput, self)


    def send(self, text):
        self.sendMessage(text)

class DataGatherCg():

    def test(self, myInput, obj):
        obj.send(myInput)

AutoBahn的SendMessage如下,在通过self后我得到一个断言错误:

def sendMessage(self,
                payload,
                isBinary=False,
                fragmentSize=None,
                sync=False,
                doNotCompress=False):
    """
    Implements :func:`autobahn.websocket.interfaces.IWebSocketChannel.sendMessage`
    """
    assert(type(payload) == bytes)

    if self.state != WebSocketProtocol.STATE_OPEN:
        return

    if self.trackedTimings:
        self.trackedTimings.track("sendMessage")

    # (initial) frame opcode
    #
    if isBinary:
        opcode = 2
    else:
        opcode = 1

    self.trafficStats.outgoingWebSocketMessages += 1

    # setup compressor
    #
    if self._perMessageCompress is not None and not doNotCompress:
        sendCompressed = True

        self._perMessageCompress.startCompressMessage()

        self.trafficStats.outgoingOctetsAppLevel += len(payload)

        payload1 = self._perMessageCompress.compressMessageData(payload)
        payload2 = self._perMessageCompress.endCompressMessage()
        payload = b''.join([payload1, payload2])

        self.trafficStats.outgoingOctetsWebSocketLevel += len(payload)

    else:
        sendCompressed = False
        l = len(payload)
        self.trafficStats.outgoingOctetsAppLevel += l
        self.trafficStats.outgoingOctetsWebSocketLevel += l

    # explicit fragmentSize arguments overrides autoFragmentSize setting
    #
    if fragmentSize is not None:
        pfs = fragmentSize
    else:
        if self.autoFragmentSize > 0:
            pfs = self.autoFragmentSize
        else:
            pfs = None

    # send unfragmented
    #
    if pfs is None or len(payload) <= pfs:
        self.sendFrame(opcode=opcode, payload=payload, sync=sync, rsv=4 if sendCompressed else 0)

    # send data message in fragments
    #
    else:
        if pfs < 1:
            raise Exception("payload fragment size must be at least 1 (was %d)" % pfs)
        n = len(payload)
        i = 0
        done = False
        first = True
        while not done:
            j = i + pfs
            if j > n:
                done = True
                j = n
            if first:
                self.sendFrame(opcode=opcode, payload=payload[i:j], fin=done, sync=sync, rsv=4 if sendCompressed else 0)
                first = False
            else:
                self.sendFrame(opcode=0, payload=payload[i:j], fin=done, sync=sync)
            i += pfs

    # if self.debug:
    #   self.log.debug("Traffic statistics:\n" + str(self.trafficStats))

2 个答案:

答案 0 :(得分:2)

使用最小样本无法重现错误,但似乎是sendMessage()不是类方法。如果不传递实例本身,则无法从类方法中调用实例方法。

尝试为send()添加另一个用于保存实例的参数,然后将self传递给该参数。类似的东西:

class MyServerProtocol(WebSocketServerProtocol):

    @classmethod
    def send(cls, self, text):
        self.sendMessage(text)

    def onMessage(self, payload, isBinary):
        msp=MyServerProtocol
        msp.send(self, 'test')

虽然在这一点上,你可能只需要send()实例方法。

答案 1 :(得分:1)

sendMessage看起来像是一个实例方法,要求它绑定到一个实例,以说明以下内容应该有效:

class MyServerProtocol(WebSocketServerProtocol):

    def onMessage(self, payload, isBinary):
        msp=MyServerProtocol
        self.sendMessage('test')