Tweepy:如何将数据从 def on_data 传递到另一个线程?

Tweepy: how do I pass data from def on_data to another thread?

我是 Python 的新手,我正在玩我的 Raspberry Pi 和 Tweepy。我通过 GPIO 连接了一些东西,我想使用情感极性值来控制电机。电机应该像心跳一样打开和关闭(打开 0.1 秒,关闭一秒钟,然后循环)。我想根据情绪极性值改变电机的 BPM。但是,如果我在代码中添加睡眠,Tweepy 自然会变慢。因此我想 运行 另一个线程中的电机代码,这样 on_data 可以 运行 没有任何睡眠代码,然后我可以在 on_data 之外做任何进一步的处理。

然而,对于我来说,我无法弄清楚如何将值传递给那个单独的线程。最简单的方法是什么?

# Twitter API imports
from tweepy.streaming import StreamListener
from tweepy import OAuthHandler
from tweepy import Stream
from textblob import TextBlob
import json
import urllib.request
import pandas as pd

# Import multithreading
from threading import Thread

# RPi Setup
import RPi.GPIO as GPIO          
from time import sleep
import time
import math

# import twitter keys and tokens (hidden for Whosebug, of course)
consumer_key= ''
consumer_secret= ''
access_token= ''
access_token_secret= ''


# ---Motor setup---
# Initiliaze motor connections
in1 = 17
in2 = 27
en = 25
temp1=1
GPIO.setmode(GPIO.BCM)

# Setup the motor
GPIO.setup(in1,GPIO.OUT)
GPIO.setup(in2,GPIO.OUT)
GPIO.setup(en,GPIO.OUT)

# Start the motor
GPIO.output(in1,GPIO.HIGH)
GPIO.output(in2,GPIO.LOW)
 
# Setup and start PWM
motorp=GPIO.PWM(en,1000)
motorp.start(0)


#  ---Arduino map function---
def _map(x, in_min, in_max, out_min, out_max):
    return int((x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min)
    
    
class TweetStreamListener(StreamListener):

    # on success
    def on_data(self, data):

        # decode json
        dict_data = json.loads(data)

        # pass tweet into TextBlob
        tweet = TextBlob(dict_data["text"])
        
        # output sentiment polarity
        print ("sentiment value: ", tweet.sentiment.polarity)

        # determine if sentiment is positive, negative, or neutral
        if tweet.sentiment.polarity < 0:
            sentiment = "negative"
        elif tweet.sentiment.polarity == 0:
            sentiment = "neutral"
        else:
            sentiment = "positive"

        # output sentiment
        print ("sentiment: ", sentiment)
        print("\n")

    # on failure
    def on_error(self, status):
        print (status)
        
        
    # Motor heart beat    
    def __init__(self):
        self._running = True
       
    def terminate(self):  
        self._running = False

    def sentiment_thread(self):
        while self._running:
            # I need 'tweet.sentiment.polarity' here to change time.sleep value, which would change according to the polarity value.
            mapped_sentiment_value = _map(tweet.sentiment.polarity, -1, 1, 1, 3)
            
            motorp.ChangeDutyCycle(100)
            time.sleep(0.1)
            motorp.ChangeDutyCycle(0)
            time.sleep(mapped_sentiment_value)
    

if __name__ == '__main__':

    # create instance of the tweepy tweet stream listener
    listener = TweetStreamListener()
    
    # start the motor heartbeat
    heartbeatthread = Thread(target=listener.sentiment_thread)
    heartbeatthread.start()
    
    # set twitter keys/tokens
    auth = OAuthHandler(consumer_key, consumer_secret)
    auth.set_access_token(access_token, access_token_secret)

    # create instance of the tweepy stream
    stream = Stream(auth, listener)

    # search twitter for "congress" keyword
    stream.filter(track=['congress'], is_async=True)

您的问题是 tweet 仅适用于您的 on_data 方法。

我的建议是将 tweet 另存为 class 属性。

def __init__(self):
    self._running = True
    self.tweet = None

def on_data(self, data):
    # decode json
    dict_data = json.loads(data)

    # pass tweet into TextBlob
    self.tweet = TextBlob(dict_data["text"])
    
    # output sentiment polarity
    print ("sentiment value: ", self.tweet.sentiment.polarity)

    # determine if sentiment is positive, negative, or neutral
    if self.tweet.sentiment.polarity < 0:
        sentiment = "negative"
    elif self.tweet.sentiment.polarity == 0:
        sentiment = "neutral"
    else:
        sentiment = "positive"

    # output sentiment
    print ("sentiment: ", sentiment)
    print("\n")


def sentiment_thread(self):
    while self._running:
        if not self.tweet:
            time.sleep(1)
            continue
        mapped_sentiment_value = _map(self.tweet.sentiment.polarity, -1, 1, 1, 3)
        motorp.ChangeDutyCycle(100)
        time.sleep(0.1)
        motorp.ChangeDutyCycle(0)
        time.sleep(mapped_sentiment_value)