Pygame从ThreadPool返回变量,在使用try赋值之前引用的局部变量,

时间:2017-09-08 01:45:07

标签: python

我试图从线程接收一些数据,但每次通过异常时,它都没有通过内部尝试,我不知道出了什么问题。我做了一次,我在每个地方搜索过。如果有人请帮忙。

def receving(name, sock): 
    while run:
        try:
            tLock.acquire()
            data = sock.recvfrom(1024)
        except:
            pass
        finally:   
            tLock.release()
        return data

host = socket.gethostbyname(socket.gethostname())
server = (host,5000)

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((host,port))
s.setblocking(0)


pool = ThreadPool(processes=1)
async_result = pool.apply_async(receving, ('arg qualquer', s))
return_val = async_result.get()
print(return_val)

run = True

while run:
    return_val = async_result.get()
    print(return_val)

错误信息是:

return data
UnboundLocalError: local variable 'data' referenced before assignment

我在尝试之前已经尝试过初始化:但输出与默认输出相同,它跳转尝试:同样的方式。 也试图使其全球化,但没有成功。

1 个答案:

答案 0 :(得分:1)

您描述的例外情况非常简单。它位于代码顶部的函数中:

def receving(name, sock):
    while run:
        try:
            tLock.acquire()
            data = sock.recvfrom(1024)
        except:
            pass
        finally:   
            tLock.release()
        return data

如果try块中的代码导致异常,则data的分配将不会运行。因此,当您稍后尝试return data时,局部变量没有值,因此它不起作用。

解决这个具体问题并不难。尝试在data = None子句中添加except或类似内容,而不仅仅是pass。这样,data将被定义(尽管可能具有不太有用的值),无论是否存在异常。

但是,您应该考虑收紧except子句,这样您就不会忽略所有例外情况。这通常是一个坏主意,因为它可以导致程序运行,即使其中的代码真的坏了。例如,您从未在您显示的代码中定义tLock,并且try会捕获因尝试获取它而导致的NameError(您仍然会遇到异常虽然当finally子句试图释放它时,所以我猜这不是你代码中的真正问题)。通常,您应该指定要捕获的异常类型。我不确定哪些对你当前的代码是正常的,所以我会把它们留给你。

如果没有合理的结果可以返回,您可能还会考虑根本没有except条款。这样,异常会“冒出”你的功能,并且调用者有责任处理它。对于某些类型的异常(例如由编程错误导致的异常,而不是预期的情况),这通常是最好的方法。

你的代码中还有很多其他奇怪的东西,所以我希望你在修复第一个问题后会遇到其他问题。例如,你总是从你的while循环的第一次迭代返回(假设我正确地修复了你的混乱缩进),所以根本没有太多意义。如果return data行实际缩进较少(它与while run处于同一级别,那么循环将使代码内部运行不止一次,但它将永远不会停止运行,因为它内部的任何内容都不会更改全局run变量的值。

也可能有其他问题,但对我来说并不是很明显你想要做什么,所以我无法帮助解决这些问题。即使对于有经验的程序员来说,多线程代码和网络编程也很难实现,所以如果你是新手,最好先从更简单的东西开始。