3

queueStream (ここには示されていません) に挿入する 1 つのスレッドと、キューが空でない場合にキューからポップする別のスレッドである 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!'

編集::::::::::::

これまでご協力いただきありがとうございました。Queue のドキュメントは素晴らしく、get() 関数がブロックされて以来 (クール!)、よりクリーンなコードを書くのに役立ちました。とにかく、それでも私の問題は解決しませんでしたが、QueueStream インスタンスを FlowController に渡す前と後で印刷しましたが、2 つの異なるメモリ位置がありました。そのため、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!'
4

2 に答える 2

1

RunStream を確認せずにこの問題をデバッグするのは困難です。そこで、問題が発生する可能性のある単純な 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!')
于 2010-09-16T16:22:57.177 に答える
0

私は Python の専門家ではありませんが、モジュール レベルの関数でもグローバル変数を宣言する必要があると思います。


def addToQueue(status):
    global queueStream
    print 'adding tweets to the queue'
    queueStream.append(status)

    #debug
    if queueStream:
        print 'queueStream is non-empty'
于 2010-09-16T17:28:45.980 に答える