在SocketServer请求之间重用变量

时间:2013-12-05 11:57:27

标签: python class variables methods udp

我想为class里面的方法创建临时变量。并更新方法内的变量。我想在内部循环中重用self.last_l。但它不起作用。

这是我的代码:

import socket, mouseapi, mouseinput
from sys import stdout, exit
from decimal import Decimal
from math import fabs
from datetime import datetime
import time
import SocketServer

UDP_IP = "192.168.1.100"
UDP_PORT = 5005


class MyUDPHandler(SocketServer.BaseRequestHandler):
    def setup(self):
        self.before = 0
        self.noise = 1.5
        self.noise_f = 0.8
        self.last_l = 0 # i want this temporary and updated on handle()

    def handle(self):
        data = self.request[0].strip()
        socket = self.request[1]
        start = time.clock()
        ndata = data.replace("[","")
        ndata = data.replace("]","")
        ndata = ndata.split(", ")        
        try:
            ndata[1] = ("%.2f" % float(ndata[1]))
            atas = ndata[1]
            atas_bawah = int(int(float(atas)*100))
            selisih = fabs(float(atas)-float(self.last_l)) # used here
            if selisih > self.noise_f:
                print "Selisih -> %.2f" % float(selisih)
                print "Sensor -> %.2f" % float(atas)
                self.last_l = atas # and updated here
                atas_bawah = int(int(float(atas)*100))
                end = time.clock()
                print "Latency -> %.2gs" % (end-start)
            if self.last_l == 0:
                self.last_l = atas # or updated here
        except KeyboardInterrupt:
            sys.exit(1)

if __name__ == "__main__":
    HOST, PORT = UDP_IP, UDP_PORT
    server = SocketServer.UDPServer((HOST, PORT), MyUDPHandler)
    server.serve_forever()

所以我希望打印selisih值小于1或更多。但它给了我超过1。

Selisih -> 6.53
Sensor -> 6.53
Latency -> 3.1e-05s
Selisih -> 6.70
Sensor -> 6.70
Latency -> 2.8e-05s
Selisih -> 6.97
Sensor -> 6.97
Latency -> 4.1e-05s
Selisih -> 7.15
Sensor -> 7.15
Latency -> 2.1e-05s
Selisih -> 7.14
Sensor -> 7.14
Latency -> 2.2e-05s
Selisih -> 7.14
Sensor -> 7.14
Latency -> 2.1e-05s
Selisih -> 7.05
Sensor -> 7.05
Latency -> 2.2e-05s
Selisih -> 7.02
Sensor -> 7.02
Latency -> 2.2e-05s

我尝试使用全局范围制作last_l。仍然行不通。

当我尝试将UnboundLocalError: local variable 'last_l' referenced before assignment后跟global last_l放置在任意位置时,我得到last_l = 0,并在self.last_l方法中将last_l更改为handle

1 个答案:

答案 0 :(得分:3)

您的处理程序无法查看self.last_l的更新,因为在每个已接受的请求上都会创建MyUDPHandler的新实例。即处理程序的实例不会被重用。

来自BaseRequestHandler docstring:

  

为每个要处理的请求实例化此类。构造函数设置实例变量request,client_address和server,然后调用handle()方法。

可能的解决方案:

  • last_l值保留在全局范围内。
  • last_l设置为self.server(在这种情况下为UDPServer的实例)
  • 使用__call__(request, client_address, server)方法将实例传递给SocketServer.UDPServer,并将经理last_l传达给那里。

注意,这些解决方案都不是线程安全的(即只能在单线程服务器上可靠地工作)。对于线程安全的解决方案,您必须使用锁保护对全局变量的写入。

第一种解决方案的例子(最简单的一种)。为清晰起见,跳过了不相关的行:

...
last_l = 0

class MyUDPHandler(SocketServer.BaseRequestHandler):
    ...
    def handle(self):
        global last_l
        ...
        selisih = fabs(float(atas)-float(last_l)) # used here
        if selisih > self.noise_f:
            ...
            last_l = atas # and updated here
            ...
        if last_l == 0:
            last_l = atas # or updated here
 ...