код становится медленным с ecxeption (Python - Raspberry - Raspian) - PullRequest
0 голосов
/ 19 сентября 2019

Я создаю программу, убирающую метеоинформацию в Интернете, и печатаю ее, когда пользователь нажимает кнопку.Я сделал новую версию программы с функцией add_event_detect от Rpio.GPIO, но программа стала очень медленной.

Я использую Raspberry Pi3B + с Raspian.

Моя программа за исключением::

def init():
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(5, GPIO.IN, pull_up_down=GPIO.PUD_UP) 
    GPIO.add_event_detect(5, GPIO.RISING, callback=bouton_presse, bouncetime=500)

def bouton_presse(channel):
    start_time = time.time()
    print "Bouton presse"
    try:
        print "Connexion"
        req=requests.get('http://www.meteo-paris.com/')
        print "Connexion reussi"
        print "Traitement du fichier html"
        soup = BeautifulSoup(req.text, 'html.parser')
        print "Soup cree"
        print "Extraction de l'information"
        elt=soup.find("div", { "class" : "bloc_aujourdhui_pluie_texte" })
        print "Info extraite"
        print "Formattage du texte"
        pourcent=elt.span.string
        print "Texte formatte"
        pluie=float(pourcent[:-1])/100
        print "pluie:",pluie
        rcol=int((1-pluie)*255)
        vcol=int(0.5*(1-pluie)*255)
        bcol=int(pluie*255)
    except:
        print "Erreut de connexion"
        rcol,vcol,bcol=255,0,0
    print "Couleurs:",rcol,vcol,bcol
    setRGB(rcol,vcol,bcol)
    print("--- %s seconds ---" % (time.time() - start_time))
    time.sleep(5)
    rcol,vcol,bcol=0,0,0
    print "Extinction"
    setRGB(rcol,vcol,bcol)


if __name__ == '__main__':
    try:
        init()
        while True:
            pass
    except KeyboardInterrupt:
        print "Shutdown requested...exiting"
    except Exception:
        traceback.print_exc(file=sys.stdout)
    GPIO.cleanup()
    sys.exit(0)

и без:

def init():
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(5, GPIO.IN, pull_up_down=GPIO.PUD_UP) 

def bouton_presse():
    start_time = time.time()
    print "Bouton presse"
    try:
        print "Connexion"
        req=requests.get('http://www.meteo-paris.com/')
        print "Connexion reussi"
        print "Traitement du fichier html"
        soup = BeautifulSoup(req.text, 'html.parser')
        print "Soup cree"
        print "Extraction de l'information"
        elt=soup.find("div", { "class" : "bloc_aujourdhui_pluie_texte" })
        print "Info extraite"
        print "Formattage du texte"
        pourcent=elt.span.string
        print "Texte formatte"
        pluie=float(pourcent[:-1])/100
        print "pluie:",pluie
        rcol=int((1-pluie)*255)
        vcol=int(0.5*(1-pluie)*255)
        bcol=int(pluie*255)
    except:
        print "Erreut de connexion"
        rcol,vcol,bcol=255,0,0
    print "Couleurs:",rcol,vcol,bcol
    setRGB(rcol,vcol,bcol)
    print("--- %s seconds ---" % (time.time() - start_time))
    time.sleep(5)
    rcol,vcol,bcol=0,0,0
    print "Extinction"
    setRGB(rcol,vcol,bcol)  


if __name__ == '__main__':
    try:
        init()
        while True:
            if GPIO.input(5)==GPIO.HIGH:
                bouton_presse()

    except KeyboardInterrupt:
        print "Shutdown requested...exiting"
    except Exception:
        traceback.print_exc(file=sys.stdout)
    GPIO.cleanup()
    sys.exit(0)

без add_event_detect занимает 0,4 с, а с add_event_detect - 2 с.Я бы предпочел использовать исключение, но 2s слишком долго!Где проблема?

1 Ответ

1 голос
/ 20 сентября 2019

Чтобы выяснить, где программа тратит время, я бы предложил что-то вроде этого:

def init():
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(5, GPIO.IN, pull_up_down=GPIO.PUD_UP) 
    GPIO.add_event_detect(5, GPIO.RISING, callback=bouton_presse, bouncetime=500)

def bouton_presse(channel):

    start_time = time.time()

    print "Bouton presse"
    try:
        print "Connexion"
        req=requests.get('http://www.meteo-paris.com/')

        req_time = time.time()

        print "Connexion reussi"
        print "Traitement du fichier html"
        soup = BeautifulSoup(req.text, 'html.parser')

        soup_time = time.time()

        print "Soup cree"
        print "Extraction de l'information"
        elt=soup.find("div", { "class" : "bloc_aujourdhui_pluie_texte" })
        print "Info extraite"
        print "Formattage du texte"
        pourcent=elt.span.string
        print "Texte formatte"
        pluie=float(pourcent[:-1])/100
        print "pluie:",pluie
        rcol=int((1-pluie)*255)
        vcol=int(0.5*(1-pluie)*255)
        bcol=int(pluie*255)

    except:
        print "Erreut de connexion"
        rcol,vcol,bcol=255,0,0

    print "Couleurs:",rcol,vcol,bcol
    setRGB(rcol,vcol,bcol)

    end_time = time.time()

    print "----- times -----"
    print "request: %s" % (req_time - start_time)
    print "parsing: %s" % (soup_time - req_time)
    print "total  : %s" % (end_time - start_time)

    time.sleep(5)
    rcol,vcol,bcol=0,0,0
    print "Extinction"
    setRGB(rcol,vcol,bcol)


if __name__ == '__main__':
    try:
        init()
        while True:
            pass
    except KeyboardInterrupt:
        print "Shutdown requested...exiting"
    except Exception:
        traceback.print_exc(file=sys.stdout)
    GPIO.cleanup()
    sys.exit(0)

Как правило, обратные вызовы такого типа должны быть короткими и быстрыми.Напротив, bouton_presse() делает запрос http и спит в течение 5 секунд.Обычно обратный вызов устанавливает глобальный флаг, и основной цикл выполняет некоторые действия, когда этот флаг установлен.

timestamp = 0

def callback(channel):
   global timestamp
   timestamp = time.time()

def main():
    prevstamp = 0

    while True:
       # if timestamp is newer, the callback must have run
       if timestamp > prevstamp:

           # handle the event
           do_something()

           # reset  
           prevstamp = timestamp
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...