处理来自另一个模块的模块变量

时间:2018-04-09 18:43:13

标签: python variables module

最近我一直试图做一些家庭助理。在主助手中,有一些在处理程序脚本中运行的模块。我导入了一个我创建的模块,通过我的覆盆子pi播放youtube视频。我想要做的是更新我的处理程序脚本中的youtube模块中的变量。以下是我到目前为止的情况:

from __future__ import unicode_literals
import subprocess
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError
import time
import urllib, json, sys
from six import string_types
from signal import pause
from omxplayer.player import OMXPlayer
from gpiozero import Button
import sys
from multiprocessing import Process
from keys import key

button_pause = Button(17)
button_quit = Button(2)
button_skip = Button(3)
var_pause = False
var_skip = False
var_quit = False

DEVELOPER_KEY = key.api_keys['YOUTUBE_API']
YOUTUBE_API_SERVICE_NAME = 'youtube'
YOUTUBE_API_VERSION = 'v3'

'''

OMXPLAYER

'''

class Player:

    def __init__(self, url):
        self.url = url
        self.player = None
        self.state = True
        self.playlist = False
        self._play = True

    def start(self):
        if isinstance(self.url, string_types):
            cmd = 'youtube-dl -g -f best {0}'.format(self.url)
            yt_dl = subprocess.Popen(cmd,shell=True, stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
            (url, err) = yt_dl.communicate()
            if yt_dl.returncode != 0:
                sys.stderr.write(err)
                print('error')
            yurl = url.decode('UTF-8').strip()
            self.player = OMXPlayer(yurl, args=['-o','hdmi'])
            return self.player.duration()

    def stop(self):
        self.player.stop()
        self._play = False
        self.player = None
        return False

    def skip(self):
        if self.playlist == True:
            self.player.stop()
            return True
        else:
            self.player.stop()
            return False

    def toggle(self):
        #false = not playing // true = playing
        if self.state == True:
            self.state = False
            self.player.pause()
        elif self.state == False:
            self.state = True
            self.player.play()
        else:
            return False

    def is_play(self):
        return self.player.can_control()






class Handlers:

    def __init__(self):
        self.url = None
        self.typeof = None
        self.proc = None
        self._play = True
        self.player = None
        self.players = None

    def input_handler(self):
        if self.typeof == 'video':
            #print(url)
            self.players = [Player(self.url)]
            self.player = self.players[0]
            print('url for video:: {0}'.format(self.player.url))
            self.player.start()
            #self.proc = Process(target = self.output_handler)
            #self.proc.start
            self.output_handler()
        elif self.typeof == 'playlist':
            for video in self.url:
                if self._play == True:
                    print(self._play)
                    #print(video)
                    self.players = [Player(video)]
                    self.player = self.players[0]
                    print('url for playlist video:: {0}'.format(self.player.url))
                    self.player.playlist = True
                    self.player.start()
                    #self.proc = Process(target = self.output_handler)
                    #self.proc.start()
                    self.output_handler()
                else:
                    return False

    def output_handler(self):
        global button_quit
        global button_pause
        global button_skip
        global var_quit
        global var_pause
        global var_skip
        if self._play == True:
            #player.start()
            time.sleep(2.5)
            p = self.player
            p.playlist = True
            if p is not None:
                try:
                    while p.is_play():
                        if self._play == True:
                            if button_quit.is_pressed:
                                p.stop()
                                self._play = False
                                return False
                            elif button_pause.is_pressed:
                                p.toggle()
                                time.sleep(1)
                            elif button_skip.is_pressed:
                                if p.playlist == True:
                                    p.skip()
                                    return True
                                else:
                                    p.stop()
                                    return False
                                time.sleep(1)

                            elif var_skip == True:
                                var_skip = False
                                if p.playlist == True:
                                    p.skip()
                                    return True
                                else:
                                    p.stop()
                                    return False
                                time.sleep(1)
                            elif var_quit == True:
                                p.stop()
                                self._play = False
                                var_quit = False
                                return False
                            elif var_pause == True:
                                print('pausing')
                                p.toggle()
                                time.sleep(1)
                                var_pause = False

                            else:
                                time.sleep(0.1)
                                print(var_pause, var_quit, var_skip)
                                global var_quit
                                global var_pause
                                global var_skip
                                p.is_play()
                        else:
                            print('not playable')
                            return False
                except Exception as e:
                    print("Something went wrong. Here it is: {0}".format(e))

注意:某些代码已被删除以用于可读性目的

您可以记下处理程序类中的Output处理程序。我想要做的是操纵另一个模块的var_skip,var_pause和var_quit,以便能够停止/播放我的视频。

在我的处理程序脚本中,我弹出一个单独的进程来运行youtube,使其在后台运行。按下时,我的按钮似乎能够熟练地更新。但是当我尝试从我的处理程序脚本访问我的变量时,没有任何反应。这是我的处理程序脚本

from modules import news
from modules import weather
from modules import sms
from modules import timers
from modules import define
from modules import youtube
from keys import key
from multiprocessing import Process, Pipe
import time
import paho.mqtt.client as mqtt
import requests
import json
import datetime
import os


############################################

mqtt_client = mqtt.Client()
HOST = key.mqtt_keys[0]
PORT = int(key.mqtt_keys[1])
TOPICS = key.mqtt_topics
timer = None
youtube_process
#API KEYS
YOUTUBE_API = key.api_keys['YOUTUBE_API']
WEATHER_API = key.api_keys['WEATHER_API']
YANDEX_API = key.api_keys['YANDEX_API']


def playVideo(query):
    global youtube_process
    youtube_process = Process(target = youtube.Youtube, args = [query,])
    youtube_process.start()






#############################################


def on_message(client, userdata, msg):
    global timer
    if msg.topic not in TOPICS:
        return False
    os.system('aplay /home/pi/snips-custom-hotword/resources/dong.wav')
    slots = parse_slots(msg)
    #print(str(slots))

    if msg.topic == 'hermes/intent/searchWeatherForecast':
        weather = getWeather()
        time = slots.get("forecast_start_datetime", None)
        location = slots.get("forecast_locality", None)
        set = handleWeather(weather, time, location)
        response = set

    elif msg.topic == 'hermes/intent/nickdeb:speakerInterrupt':
        global youtube_process
        keyword = slots.get("keyword", None)
        if keyword:
            if keyword == 'pause' or keyword == 'Pause' or keyword == 'paused':
                response = 'Pausing your music!'
                youtube_process.var_pause = True
            else:
                response = 'Stopping your music'
                youtube_process.var_quit = True
        else:
            response = 'Stopping your music!'
            youtube.var_quit = True
    elif msg.topic == 'hermes/intent/nextSong':
        youtube.var_skip = True
        response = 'Skipping your song'

    elif msg.topic == 'hermes/intent/resumeMusic':
        youtube.var_pause = True
        response = 'Resuming your music!'

    elif msg.topic == 'hermes/intent/playArtist':
        query = slots.get("artist_name", None) + ' top tracks'
        youtubes = playVideo(query)
        response = 'Playing top tracks by {1}'.format(msg.topic, slots.get("artist_name", None))
    elif msg.topic == 'hermes/intent/nickdeb:playSong':
        youtubes = playVideo(slots.get("song_name", None))
        response = 'Playing {0} for you'.format(slots.get("song_name", None))

我已经尝试过编辑流程的模块变量和常规模块变量,但没有任何工作。请帮忙!谢谢!

TLDR;从处理程序脚本更改模块变量并实时更新它。模块位于进程内部,变量是我想要访问的全局变量。该变量在类

中使用

1 个答案:

答案 0 :(得分:0)

创建单独的流程时,当前全局状态将复制到新流程。您之后所做的任何更改(如更改全局变量)都不会与其他进程共享。

multiprocessing包具有帮助share state between processes

的工具

在这种情况下,您可能希望使用Manager在进程之间共享这些设置,而不是全局变量。

from multiprocessing import Manager, Process

manager = Manager()
state = manager.dict()
state['pause'] = False
state['skip'] = False
state['quit'] = False

youtube_process = Process(target = youtube.Youtube, args=(query, state))

# Process will get this change.
state['quit'] = True