【问题标题】:Reusing variable between SocketServer requests在 SocketServer 请求之间重用变量
【发布时间】:2013-12-22 08:35:48
【问题描述】:

我想为类中的方法创建临时变量。并更新方法内部的变量。我想在循环内重用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 具有全局范围。还是不行。

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

【问题讨论】:

  • 你能解释一下it doesn't work到底是什么意思吗?
  • 题外话:我看到你是印度尼西亚人.. :) Jarang ketemu orang indo disini XD
  • 你确定你的 try 块后面的语句运行没有错误吗?我首先猜想你在某个地方得到了 ValueError 并且一直只运行 pass 行。请注意,简单地通过 ValueErrors 并不是一个好的例程,因为它们可能会为您提供有关错误所在位置的宝贵信息。
  • 它不起作用,因为self.last_l 和我不能重复使用self.last_l
  • @Gunslinger_ 尝试从except ValueError 子句打印一些内容,以检查它是否发生。

标签: python class variables methods udp


【解决方案1】:

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

来自BaseRequestHandler 文档字符串:

为每个要处理的请求实例化此类。构造函数设置实例变量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
 ...

【讨论】:

  • 会为每个实例调用 setup 吗?
  • 那么你有什么解决办法吗?
  • @Sorin,是的——每个新实例都会调用setup()
  • @Gunslinger_,我已经为答案添加了可能的解决方案,如果您需要更详细的解释,请告诉我。
  • @Gunslinger_,请参阅更新答案中的示例。我认为您错误地使用了global
猜你喜欢
  • 2013-04-12
  • 2014-03-23
  • 1970-01-01
  • 2011-12-27
  • 2017-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多