【问题标题】:How to transfer a value from a function in one script to another script without re-running the function (python)?如何在不重新运行函数(python)的情况下将一个脚本中的函数的值传输到另一个脚本?
【发布时间】:2017-12-24 22:58:18
【问题描述】:

我对一般编程真的很陌生,而且非常缺乏经验,我正在学习 python,因为我认为它比其他语言更简单。无论如何,我正在尝试将 Flask-Ask 与 ngrok 一起使用来编写 Alexa 技能以在线检查数据(每小时更改几次)。该脚本采用四个不同的数字(来自不同的 URL)并将其组织成字典,并使用 Selenium 和 phantomjs 访问数据。

显然,这超过了 8-10 秒的最大运行时间,然后 Alexa 决定它花费了太长时间并返回错误消息(我知道它的超时为 ngrok,如果发生实际错误,python 日志将显示,它总是在 8-10 秒后发生,即使在 8-10 秒后它应该在脚本中间)。我读过我可以重新提示它,但我不知道怎么做,这只会给我多 8-10 秒的时间,而脚本通常需要大约 25 秒才能从互联网上获取数据(然后也许一秒钟把它变成字典)。

我尝试将 getData 函数放在第一次调用 Alexa 技能时运行的意图之后,但它仅在我初始化本地服务器时运行,并且仅保存每个新 Alexa 会话的数据。因为数据经常变化,所以我希望它在每次使用 Alexa 开始新的技能会话时执行该功能。

因此,我决定将实际获取数据的函数外包给另一个脚本,并让另一个脚本不断循环运行。这是我使用的代码。

import time

def getData():
  username = '' #username hidden for anonymity
  password = '' #password hidden for anonymity
  browser = webdriver.PhantomJS(executable_path='/usr/local/bin/phantomjs')
  browser.get("https://gradebook.com") #actual website name changed
  browser.find_element_by_name("username").clear()
  browser.find_element_by_name("username").send_keys(username)
  browser.find_element_by_name("password").clear()
  browser.find_element_by_name("password").send_keys(password)
  browser.find_element_by_name("password").send_keys(Keys.RETURN)
  global currentgrades
  currentgrades = []
  gradeids = ['2018202', '2018185', '2018223', '2018626', '2018473', '2018871', '2018886']
  for x in range(0, len(gradeids)):
    try:
        gradeurl = "https://www.gradebook.com/grades/"
        browser.get(gradeurl)
        grade = browser.find_element_by_id("currentStudentGrade[]").get_attribute('innerHTML').encode('utf8')[0:3]
        if grade[2] != "%":
            grade = browser.find_element_by_id("currentStudentGrade[]").get_attribute('innerHTML').encode('utf8')[0:4]
        if grade[1] == "%":
            grade = browser.find_element_by_id("currentStudentGrade[]").get_attribute('innerHTML').encode('utf8')[0:1]
        currentgrades.append(grade)
    except Exception:
        currentgrades.append('No assignments found')
        continue
  dictionary = {"class1": currentgrades[0], "class2": currentgrades[1], "class3": currentgrades[2], "class4": currentgrades[3], "class5": currentgrades[4], "class6": currentgrades[5], "class7": currentgrades[6]}
  return dictionary

def run():
  dictionary = getData()
  time.sleep(60)

该脚本不断运行并执行我想要的操作,但是在我的其他脚本中,我不知道如何调用字典变量。当我使用 from getdata.py import dictionary 在 Flask-ask 脚本中,它只是运行循环并不断获取数据。我只希望 Flask-ask 脚本获取“运行”函数中定义的变量,然后使用它而不运行 getdata 脚本中定义的任何实际脚本,这些脚本已经运行并获得了正确的数据。如果重要的话,这两个脚本都在 MacBook 上的终端中运行。

有什么方法可以解决我的问题,还是有更简单的解决方法?感谢您提供任何和所有帮助!

【问题讨论】:

  • 能否在您的问题中包含 getData 函数?此外,您是否尝试多次获取 alexa 意图调用的数据?如果是这样,为什么您不能在通话前获取数据?只是想更好地理解一点,以便我能提供帮助。
  • 我在问题中添加了函数。我基本上是在尝试在 Alexa 意图调用之前组合多条数据并形成字典。理想情况下,我想在调用之前获取数据,但由于它经常更改,我认为我需要在调用技能后获取数据,并且每当我尝试获取数据时 Alexa 都会超时。
  • 我尝试将 getData() 函数放在脚本之前,它运行一次来​​初始化脚本,但每次我开始与 Alexa 的新会话时都不会重新检查数据(这使得有道理,但这仍然不是我想要的)。如果我把它作为自己的意图,它就会超时。有没有什么方法可以运行这个脚本,每次我询问 Alexa 时都需要十多秒才能完成并获取最新数据?

标签: python flask transfer


【解决方案1】:

听起来你要导入函数,所以你可以运行它;而不是导入字典。

尝试删除run 函数,然后在您的其他脚本中

from getdata import getData

然后,每次您编写 getData() 时,它都会运行您的代码并获取一个新的最新字典。

这是你要问的吗?

【讨论】:

  • 嗯,问题是我不知道如何在没有 Alexa 脚本超时的情况下获取新的最新字典。在 Alexa 运行意图返回答案后,我有 8 秒的时间,然后 Alexa 放弃等待并返回错误,这不足以更新字典。所以,我需要以某种方式更新意图或其他东西之间的字典。
  • @ProgrammerWhoCannotProgram 同样的问题,为什么你不能每次在创建alexa意图之前调用getData(),每次(即更新意图之间的字典,如你所说) ?
  • @forumulator 这就是我想做的,我就是不知道怎么做。一旦调用了意图,它就会运行一个函数,我有 10 秒的时间来返回一个值(这会结束函数)。我尝试将脚本放在两个意图定义之间,但它只是在我初始化脚本时运行,并且实际上并没有在它上面的意图之后在下面的意图之前运行(正如我应该预料的那样)。我的解决方案是在启动 Intent 的同时运行它,这样启动 Intent 可以返回它的值,但 getData() 会继续运行,当你需要字典时,它就完成了。
【解决方案2】:

此问题已解决。

至于最初的问题,我没有弄清楚如何让它只是导入字典而不是首先运行函数来生成字典。此外,我意识到必须有一个更实用的解决方案,而不是不断运行这样的脚本,即使这样也得不到全新的数据。

我的解决方案是让获取数据的脚本与启动函数同时开始运行。这是第一个意图的最终脚本(其余部分保持不变):

@ask.intent("start_skill")

def start_skill():
    welcome_message = 'What is the password?'
    thread = threading.Thread(target=getData, args=())
    thread.daemon = True
    thread.start()
    return question(welcome_message)

def getData():
  #script to get data here

#other intents and rest of script here

按照设计,该技能要求输入数字密码,以确保我是使用它的人,然后才愿意读取数据(这可能毫无意义,但这项技能至少与我自己的教育原因一样重要实际的原因,所以,为了额外的练习,我希望它具有尽可能多的特性)。因此,当您真正能够请求数据时,获取数据的脚本将完成运行(我已经对此进行了测试,它似乎可以正常工作)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多