【问题标题】:Importing python variables of a program after its execution执行后导入程序的python变量
【发布时间】:2011-03-30 21:08:09
【问题描述】:

我编写了两个 python 脚本 script1.py 和 script2.py。我想从 script2.py 运行 script1.py 并获取 script1 执行期间创建的 script1 变量的内容。 Script1 有几个函数可以在其中创建变量,包括在主函数中。

感谢您的所有回答。我已经检查了您的答案,但它似乎不起作用。 以下是我所说的有罪脚本:

script1.py

def main(argv):
    """Main of script 1
    Due to the  internal structure of the script this 
    main function must always be called with the flag -d
    and a corresponding argument.
    """
    global now
    now = datetime.datetime.now()

    global vroot_directory
    vroot_directory = commands.getoutput("pwd")

    global testcase_list_file
    testcase_list_file = 'no_argument'

    try:
        opts, args = getopt.getopt(argv, "d:t:", 
            ["directory_path=", "testcase_list="])
    except getopt.GetoptError, err:
        print command_syntax
        sys.exit()
    for opt, arg in opts:
        if opt in ("-d", "--directory"):
            vroot_directory = arg
        if opt in ("-t", "--testcase"):
             testcase_list_file = arg

    def function1():
        pass  

    def function2():
        if testcase_list_file == 'no_argument':
            function1()
        else:
            function2()

if __name__ == "__main__":
    main(sys.argv[1:]) 

script2.py

from Tkinter import *

class Application:
    def __init__(self):
        """ main window constructor """
        self.root = Tk()
        # I'd like to import here the variables of script1.py
        self.root.title(script1.vroot_directory)   ?
        self.root.mainloop()

# Main program
f = Application()

抱歉我的错误并感谢您的中肯评论。我收到以下错误消息:

" AttributeError: 'module' 对象没有属性 'vroot_directory'"

更具体地说,我想要类似于以下内容:

from Tkinter import *
import script1

class Application:
    def __init__(self):
        """ main window constructor """
        self.root = Tk()
        script1.main(-d directory -t testcase_list_file) # to launch script1
        self.root.title(script1.vroot_directory)   # and after use its variables and functions
        self.root.mainloop()

# Main program
f = Application()

【问题讨论】:

  • 我已经清理了你的代码;在这里发布时应该使用良好的格式。错误是什么?你写的应该可以工作。
  • 如果那是script2.py全部 内容,那当然不行——你还没有包含import script1!正如我和其他几个人在下面所说的那样。
  • 从您的帖子中,我得到的印象是您想要运行 script1,然后在未来的某个时间能够运行脚本 2 并且仍然获得在 script1 中设置的值。对吗?
  • 是的,并且 script1 必须从 script2 运行。没有导入或命令(如 os.system)能够做到这一点?

标签: python variables import main


【解决方案1】:

我认为您正在寻找的是某种形式的对象持久性。我个人为此使用搁置模块:

脚本 1:

import shelve

def main(argv):
    """Main of script 1
    Due to the  internal structure of the script this 
    main function must always be called with the flag -d
    and a corresponding argument.
    """

    settings = shelve.open('mySettings')

    global now
    now = datetime.datetime.now()

    settings['vroot_directory'] = commands.getoutput("pwd")

    settings['testcase_list_file'] = 'no_argument'

    try:
        opts, args = getopt.getopt(argv, "d:t:", 
            ["directory_path=", "testcase_list="])
    except getopt.GetoptError, err:
        print command_syntax
        sys.exit()
    for opt, arg in opts:
        if opt in ("-d", "--directory"):
            settings['vroot_directory'] = arg
        if opt in ("-t", "--testcase"):
            settings['testcase_list_file'] = arg

    def function1():
        pass  

    def function2():
        if testcase_list_file == 'no_argument':
            function1()
        else:
            function2()

if __name__ == "__main__":
    main(sys.argv[1:]) 

脚本 2:

from Tkinter import *
import shelve

class Application:
    def __init__(self):
        settings = shelve.open('mySettings')

        """ main window constructor """
        self.root = Tk()
        # I'd like to import here the variables of script1.py
        self.root.title(settings['vroot_directory'])   ?
        self.root.mainloop()

# Main program
f = Application()

搁置模块在其实现中使用了 pickle 模块,因此您还可以查看 pickle 模块的另一种方法。

【讨论】:

  • 谢谢!我将尝试这种方法。
  • 我已经尝试过了,但不幸的是它不起作用,出现以下消息:keyError:'vroot_directory'(如果我现在尝试获取另一个变量,我会收到相同的消息)
  • @Bruno - 如果您遇到关键错误,有几种可能的解释。两个程序是否从同一目录运行?如果您检查从哪里调用文件及其容器目录,您会找到 mySettings 文件吗?您可能需要在两个脚本中提供 shelve.open() 的完整路径,以确保它们拾取相同的对象。
  • 感谢您的提示。我查看了 mySettings 文件,它位于正确的目录中。我已经将路径更改为绝对路径,结果是一样的。要启动我在 script2.py 中尝试过的程序 an os.system(" ./script.py -d directory -t testcase_list_file") (在 script1.py 上执行 chmod +x 之后),我收到了消息 sh: script1.py:在终端上找不到命令。 rgds,
  • 我的错误:再试一次,一切都很好!非常感谢 gddc 和大家的时间和帮助。 rgds,
【解决方案2】:

来自script2

import script1

这将运行script1 中的任何代码;任何全局变量都将可用,例如script1.result_of_calculation。您可以如下设置全局变量。


脚本1:

from time import sleep
def main( ):
    global result
    sleep( 1 ) # Big calculation here
    result = 3

脚本2:

import script1
script1.main( ) # ...
script1.result # 3

请注意,让 script1 中的main() 返回result更好,这样你就可以这样做

import script1
result = script1.main( )

这更好地封装了数据流,并且通常更 Pythonic。它还避免了全局变量,这通常是一件坏事。

【讨论】:

    【解决方案3】:

    有两种可能:首先,将它们合并到一个脚本中。这可能看起来像(在 script2.py 中)

    import script1
    
    ...
    script1.dostuff()
    importantvar = script1.importantvar
    doScript2Stuff(importantvar)
    

    但是,在不了解您的应用程序的情况下,我建议将 script1 所做的任何事情封装到一个函数中,以便您可以简单地调用

    (var1, var2, var3) = script1.dostuffAndReturnVariables()
    

    因为避免全局变量总是好的。此外,如果 script1 中的内容在您导入它的那一刻没有执行(因为如果您直接在主级别上编写所有命令,则它可能会在稍后变得方便),但是当您需要它时,通过调用一个函数。否则,一旦您获得更多模块,事情可能会变得一团糟,并且您可能会发现自己重新排列导入命令,因为它们做了很多事情。

    第二种可能,如果由于某种原因需要单独运行它们,那就是使用pickle。

    output = open(picklefile, "w")
    pickle.dump(vars, output)    
    output.close()
    

    在 script1.py 中

    然后

    inputfile = open(picklefile, "r")
    vars = pickle.load(inputfile)
    input.close()
    

    在 script2.py 中。这样,您可以将 var 的内容保存在一个文件中,并在需要时从那里恢复它们。

    但是,我更喜欢第一种方法,除非有充分的理由不将两者一起运行,因为它可以改进代码的结构。

    【讨论】:

      【解决方案4】:

      Python 是一种解释型语言,因此当您在另一个脚本中简单地导入一个脚本时(例如,通过在 script2 中写入 import script1),解释器将加载第二个脚本并逐步执行它。每个函数定义都会产生一个可调用的函数对象等等,每个表达式都会被简单地执行。

      之后,您可以使用script1.globalvar1 等访问模块中的所有内容。

      【讨论】:

      • 这种行为真的与 python 作为解释语言有关吗? (不是反问;)
      • 这个概念至少不适用于链接语言,因为在链接过程中只设置了一些引用,但没有执行任何语句。在这样的语言中,您必须将所有内容放在初始化函数中并手动调用它。
      【解决方案5】:

      根据您要传递给 script2.py 的变量数量,您可以通过参数传递它们并将它们作为 argv 数组拾取。你可以运行 script1.py 然后从这个脚本运行 os.system('script2.py arg0 arg1 arg2 arg3') 来调用 script2.py。

      然后您可以通过执行以下操作在 script2.py 中获取变量:

      import sys
      
      arg0 = sys.argv[0]
      arg1 = sys.argv[1]
      ...
      

      【讨论】:

      • -1 你不应该使用命令行在 Python 模块之间进行通信。
      • 当然,这只是一个建议,也许这是在他的情况下,他可以实现目标的唯一方法。
      • 好吧,好吧,但我想不出在任何情况下你必须这样做。 pickle 如果不能在运行时传递数据,那将是一种更好的方式。
      猜你喜欢
      • 2014-06-09
      • 2019-07-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-01
      • 1970-01-01
      • 2014-03-23
      • 1970-01-01
      相关资源
      最近更新 更多