Python作用域和线程问题
我有一个线程插入queueStream(此处未显示)和FlowController,如果队列不是空的,它是从队列弹出的另一个线程 我使用addToQueue()中的调试代码验证了数据是否正确插入队列 问题是,FlowController中的“if queueStream”语句总是将queueStream视为空,而转到else语句 我是Python新手,我觉得我缺少一些简单的范围规则。我正在使用“全局队列流”,但它似乎没有任何作用 谢谢你的帮助Python作用域和线程问题,python,multithreading,scoping,Python,Multithreading,Scoping,我有一个线程插入queueStream(此处未显示)和FlowController,如果队列不是空的,它是从队列弹出的另一个线程 我使用addToQueue()中的调试代码验证了数据是否正确插入队列 问题是,FlowController中的“if queueStream”语句总是将queueStream视为空,而转到else语句 我是Python新手,我觉得我缺少一些简单的范围规则。我正在使用“全局队列流”,但它似乎没有任何作用 谢谢你的帮助 from stream import * from
from stream import *
from textwrap import TextWrapper
import threading
import time
queueStream = []
class FlowController(threading.Thread):
def run(self):
global queueStream
while True:
if queueStream:
print 'Handling tweet'
self.handleNextTweet()
else:
print 'No tweets, sleep for 1 second'
time.sleep(1)
def handleNextTweet(self):
global queueStream
status = queueStream.pop(0)
print self.status_wrapper.fill(status.text)
print '\n %s %s via %s\n' % (status.author.screen_name, status.created_at, status.source)
def addToQueue(status):
print 'adding tweets to the queue'
queueStream.append(status)
#debug
if queueStream:
print 'queueStream is non-empty'
if __name__ == '__main__':
try:
runner = RunStream()
runner.start()
flow = FlowController()
flow.start()
except KeyboardInterrupt:
print '\nGoodbye!'
编辑:
谢谢你迄今为止的帮助。队列文档很好,帮助我编写了更干净的代码,因为get()函数阻塞了(很酷!)。无论如何,它仍然没有解决我的问题,但我在将queueStream实例传递给FlowController之前和之后打印了它,它们有两个不同的内存位置。这就是为什么我相信FlowController中没有从队列中弹出任何内容。这是否意味着Python通过值而不是引用传递queueStream?如果是这样,我该如何应对
from stream import *
from textwrap import TextWrapper
from threading import Thread
from Queue import Queue
import time
class FlowController(Thread):
def __init__(self, queueStream):
Thread.__init__(self)
self.queueStream=queueStream
def run(self):
while True:
status = self.queueStream.get()
print self.status_wrapper.fill(status.text)
print '\n %s %s via %s\n' % (status.author.screen_name, status.created_at, status.source)
def addToQueue(status):
print 'adding tweets to the queue'
queueStream.put(status)
queueStream = Queue()
if __name__ == '__main__':
try:
runner = RunStream()
runner.start()
flow = FlowController(queueStream)
flow.start()
except KeyboardInterrupt:
print '\nGoodbye!'
如果不看到RunStream,就很难调试这个问题。 所以我试着想出一个简单的运行流,可能会出现这个问题 我无法重现该问题,但该代码似乎有效。 如果它确实有效,并且与您的RunStream非常相似,那么您可以将此代码与您自己的代码进行比较,找出错误所在
import threading
import time
import Queue
import sys
import random
class FlowController(threading.Thread):
def __init__(self,queueStream):
threading.Thread.__init__(self)
self.queueStream=queueStream
def run(self):
while True:
if not self.queueStream.empty():
print 'Handling tweet'
self.handleNextTweet()
else:
print 'No tweets, sleep for 1 second'
time.sleep(1)
def handleNextTweet(self):
status = self.queueStream.get()
print(status)
class RunStream(threading.Thread):
def __init__(self,queueStream):
threading.Thread.__init__(self)
self.queueStream=queueStream
def run(self):
i=0
while True:
addToQueue(self.queueStream,i)
i+=1
time.sleep(random.randint(0,2))
def addToQueue(queueStream,status):
print 'adding tweets to the queue'
queueStream.put(status)
if not queueStream.empty():
print 'queueStream is non-empty'
if __name__ == '__main__':
queueStream = Queue.Queue()
try:
runner = RunStream(queueStream)
runner.daemon=True
runner.start()
flow = FlowController(queueStream)
flow.daemon=True
flow.start()
time.sleep(100)
except KeyboardInterrupt:
pass
finally:
print('Bye!')
我不是python专家,但我相信即使在模块级函数中也必须声明全局变量
def addToQueue(status):
global queueStream
print 'adding tweets to the queue'
queueStream.append(status)
#debug
if queueStream:
print 'queueStream is non-empty'
RunStream()是另一个线程,它调用addToQueue(status)函数并将状态添加到队列中。你可能还想看看,也许会让生活更轻松一些:)我支持@bronzebeard的评论。如果你想快速,不要使用线程。至少在CPython中是这样。如果要将新值分配给
queueStream
并使该值可以通过名称queueStream
在其他名称空间中访问,则只需使用global queueStream
。这里,正在对queueStream
调用一个方法。无论是否声明queueStream
为global
,此效果都是可见的,因为没有重新分配标识符。啊,很有趣。我会留下这个答案,即使它不正确,因为其他人可能会发现你的评论有用谢谢,虽然我没有使用这个解决方案,但它给了我解决这个问题的基本思路。我没有包括RunStream,因为它使用了一个库,并且有点混乱。基本上为了解决这个问题,我将addToQueue()和queueStream移动到FlowController中,然后将FlowController的一个实例传递给RunStream,这样它就可以将addToQueue直接传递给FlowController的实例。FlowController访问queueStream没有问题,因为它现在在该类中。谢谢大家的帮助