Python 作用域和线程问题
我有一个线程插入到queueStream(此处未显示)和FlowController中,这是另一个线程,如果队列不为空,则从队列中弹出。
我使用 addToQueue() 中的调试代码验证了数据是否已正确插入队列。
问题是,FlowController 中的“if queueStream”语句始终将queueStream 视为空,而是转到 else 语句。
我是 Python 新手,我觉得我缺少一些简单的作用域规则。我正在使用“全局队列流”,但它似乎没有做任何事情。
感谢您的任何帮助。
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!'
I have one thread that inserts into the queueStream (not shown here) and FlowController which is another thread that pops from the queue if the queue is not empty.
I verified that the data is inserted into the queue correctly with the debug code in addToQueue()
Problem is, the 'if queueStream' statement in FlowController always sees the queueStream as empty, and instead goes to the else statement.
I'm new to Python and I feel I'm missing some simple scoping rules of some kind. I am using the 'global queueStream' but that appears to not be doing anything.
Thanks for any help.
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!'
EDIT::::::::::::
Thanks for the help so far. The Queue documentation is nice and has helped me write cleaner code since the get() function blocks (cool!). Anyway, it still did not solve my problem, but I printed out the queueStream instance before passing it to FlowController and after, and they had two different memory locations. That is why I believe nothing is being popped from the queue in FlowController. Does that mean that Python passes queueStream by value and not by reference? If so, how do I get around that?
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!'
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果没有看到 RunStream,很难调试这个问题。
因此,我尝试设想一个可能会出现该问题的简单 RunStream。
我无法重现该问题,但这段代码似乎有效。
如果它确实有效并且与您的 RunStream 足够相似,也许您可以将此代码与您自己的代码进行比较以找出问题所在。
It's hard to debug this problem without seeing RunStream.
So I tried to dream up a simple RunStream that might exhibit the problem.
I wasn't able to reproduce the problem, but this code seems to work.
If it does work and is similar enough to your RunStream, perhaps you can compare this code to your own to find what's wrong.
我不是 python 专家,但我相信即使在模块级函数中也必须声明全局变量
I'm not a python expert, but I believe you have to declare your global variables even in module level functions