【问题标题】:Pass variable between python scripts在 python 脚本之间传递变量
【发布时间】:2020-07-05 23:24:41
【问题描述】:

我确信这很简单,但我一直无法让它正常工作。我需要让我的主要 python 脚本调用另一个 python 脚本并将变量从原始脚本传递给我调用的脚本

所以对于一个简单的例子,我的第一个脚本是,

first.py
x = 5
import second

我的第二个脚本是,

second.py 
print x

我希望它打印 x 但我得到了

NameError: name 'x' is not defined

我不确定导入是否是实现这一目标的正确方法,但如果有人能以简单的方式阐明它,那就太好了!

谢谢,


编辑

阅读完 cmets 后,我想我会扩展我的问题。 Aswin Murugesh 的回答解决了我遇到的导入问题,但是该解决方案没有达到预期的结果,因为我似乎无法以这种方式传递列表中的项目。

在 first.py 我有一个列表,我处理如下

for insert, (list) in enumerate(list, start =1):
    'call second.py passing current list item'

我想将列表中的每个项目传递给第二个 python 文件以进行进一步处理(网络抓取),我不想在 first.py 中执行此操作,因为这是主“扫描”程序然后调用其他程序。我希望这现在更有意义。

感谢到目前为止的 cmets。

【问题讨论】:

  • 这两个脚本有什么办法可以成为单个脚本中的函数吗?
  • @summea 不是一个真正有用的回应。是的,我想 OP 可以尝试通过从不使用导入,永远来解决不理解 Python 导入系统的基础知识的问题,但是当他需要从他目前的困惑是一个小代码 sn-p 显示如何使用导入?
  • 与某些语言不同,Python 的import 不只是将导入文件的源代码转储到包含文件的中间并执行整个过程。导入的文件对其周围环境一无所知,这就是该代码中断的原因。在您的情况下,我不确定导入是否正确。适当的模块化建议设计 second.py 以便可以将 x 作为参数传递给其中定义的函数/对象。
  • @MarkAmery 仅尝试提出不同的方法,如果可能的话。
  • Stjepan Bakrac 的回应是这里所说的最有帮助的事情。您还没有充实您的场景,我们无法确定什么是合适的,但是从您所写的内容来看,我猜first 本质上是一个“主”模块-您程序的概念上自然的入口点-但是您想将一些逻辑分离到second。这很好,但如果是这样,您需要在 second 中创建一个函数(或多个函数,或一个或多个类),该函数将 first 中所需的变量作为参数。

标签: python


【解决方案1】:

调用脚本时,调用脚本可以访问被调用脚本的命名空间。 (在您的情况下,first 可以访问 second 的命名空间。)但是,您要求的是相反的方式。您的变量在调用脚本中定义,并且您希望被调用脚本访问调用者的命名空间。

这个 SO 帖子中已经在问题本身中说明了答案:

Access namespace of calling module

但我将在您的上下文中解释它。

要在您的情况下获得您想要的,请使用以下行开始调用的脚本:

from __main__ import *

这允许它访问调用者脚本的命名空间(所有变量和函数)。

所以现在你的调用脚本和以前一样:

x=5
import second

调用的脚本是:

from __main__ import *
print x

这应该可以正常工作。

【讨论】:

  • 实际上我只是用一个列表检查了它,它似乎不起作用,第二个程序只为列表中的第一项调用一次,而我需要为每个项目按顺序调用它一个新的实例。似乎如果我第二次调用 timer.sleep() 它会停止主程序(第一次)...?
【解决方案2】:

使用以下脚本:

first.py:

x=5

second.py

import first
print first.x

这将打印 x 值。始终导入的脚本数据应使用脚本名称引用,如 first.x

【讨论】:

  • 或者,from first import x 后跟print x 另外,应该说import first,而不是import first.py
  • 如果你想传递一个随机生成的哈希码是行不通的。
【解决方案3】:

为避免命名空间污染,请单独导入所需的变量:from __main__ import x,依此类推。否则,您最终会遇到您不知道的命名冲突。

【讨论】:

    【解决方案4】:

    尝试使用 exec Python3.5:

    first.py

    x=5
    exec(open('second.py').read())
    

    second.py

    print(x)
    

    您也可以通过以下方式传递 x:

    x=5
    myVars = {'x':x}
    exec(open('second.py').read(), myVars)
    

    不确定这是否是一个好方法。

    【讨论】:

      【解决方案5】:

      最后,

      我为 Python 创建了一个包来解决这个问题。


      从 PIP 安装 Guli。

      $ pip install guli
      

      Guli 不需要安装任何额外的 PIP 包。

      有了这个包就可以了

      Guli 可用于在不同的 Python 脚本之间、在多个进程之间或在同一个脚本之间传递。 在主进程和另一个(多进程)进程之间传递变量。

      • 在不同的 Python 脚本之间传递变量。
      • 在“主进程”和另一个(多进程)进程之间传递变量。
      • 在同一脚本中使用变量。
      • 创建/删除/编辑 - GuliVariables。

      示例

      import guli
      import multiprocessing
      
      string = guli.GuliVariable("hello").get()
      print(string) # returns empty string ""
      
      def my_function():
        ''' change the value from another process '''
        guli.GuliVariable("hello").setValue(4)
      
      multiprocessing.Process(target=my_function).start()
      
      import time
      time.sleep(0.01) # delay after process to catch the update
      
      
      string = guli.GuliVariable("hello").get()
      print(string) # returns "success!!!"
      

      希望我为很多人解决了这个问题!

      【讨论】: