简体   繁体   English

将变量从一个Python脚本发送到另一个

[英]Send a Variable from one Python Script to another

I have a python script that is constantly listening out for a json message from another server. 我有一个python脚本,不断侦听来自另一台服务器的json消息。 When it receives a message one of the values is placed into a variable. 当它收到一条消息时,其中一个值将被放入变量中。 Once this message is received I need another python script to be launched and the variable past over to it to be processed. 收到此消息后,我需要启动另一个python脚本,并将变量传递给它进行处理。 Can anyone help me with how to do this? 谁能帮助我做到这一点?

I'm very new to python and would really appreciate any help you can give me, as I'm struggling to understand some of the other answers to similar questions. 我是python的新手,非常感谢您能为我提供的任何帮助,因为我正努力了解类似问题的其他一些答案。

Thank you! 谢谢!

Below is the code constantly running to receive messages: 下面是不断运行以接收消息的代码:

class MyListener(stomp.ConnectionListener):
    def on_error(self, headers, message):
        print 'received an error %s' % message

    def on_message(self, headers, message):
        print 'received a message %s' % message
        obj = json.loads(message)
        detectedimsi = obj["imsi"]
        print detectedimsi

You'll need the subprocess module: 您将需要subprocess模块:

import subprocess

Then in your on_message() method, you can start the other process: 然后,在on_message()方法中,可以启动其他过程:

  def on_message(self, headers, message):
    …
    outputOfOtherProcess = subprocess.check_output([
      '/path/to/other/process',
      json.dumps(detectedimsi) ])

Your other process will receive the value you want to pass as sys.argv[1] in JSON format (so it will need to use json.loads(sys.argv[1]) ). 您的其他进程将以JSON格式接收要作为sys.argv[1]传递的值(因此它将需要使用json.loads(sys.argv[1]) )。

Other ways of passing the value are possible, but passing it as command line argument might be sufficient for your case (depends on the data's size and other things). 传递值的其他方式也是可行的,但对于您的情况,将其作为命令行参数传递可能就足够了(取决于数据的大小和其他因素)。

As abarnert pointed out, some things should be mentioned: 正如abarnert指出的,应该提到一些事情:

  • This way of calling a subprocess will block until the subprocess is finished. 这种调用子流程的方法将阻塞,直到子流程完成为止。 This might be a problem in case your script is supposed to be reactive again before the subprocess is finished. 如果您的脚本在子过程完成之前应该再次处于响应状态,则可能会出现问题。
  • Calling the subprocess script by giving its path as executable might fail on systems which do not provide the direct calling of scripts. 在不提供脚本直接调用的系统上,通过将子进程脚本的路径指定为可执行文件来调用它可能会失败。 In these cases you will have to call the interpreter (which can be accessed as sys.executable ) and pass the path to the script as first parameter instead (and the remaining parameters after that). 在这些情况下,您将必须调用解释器(可以通过sys.executable进行访问),并将路径传递到脚本作为第一个参数(以及之后的其余参数)。

To run any other program, you just use the functions in the subprocess module. 要运行任何其他程序,只需使用subprocess模块中的功能。 But there are three complexities. 但是有三个复杂性。

First, you want to run another Python script, not a binary. 首先,您要运行另一个Python脚本,而不是二进制文件。 Presumably you want to run it with the same version of Python that you're running in, even if there are multiple Pythons installed. 即使安装了多个Python,大概也要使用与您运行的Python版本相同的软件来运行它。 So, you want to use sys.executable as the program. 因此,您想使用sys.executable作为程序。 For example: 例如:

subprocess.check_call([sys.executable, 'otherscript.py'])

Second, you want to pass some data. 其次,您要传递一些数据。 For small amounts of printable string data that will fit on the command line, just pass them as an argument: 对于适合命令行的少量可打印字符串数据,只需将它们作为参数传递:

subprocess.check_call([sys.executable, 'otherscript.py', detectedimsi])

Then, in the other script, you just look at sys.argv[1] to receive the data. 然后,在另一个脚本中,您只需查看sys.argv[1]即可接收数据。

If you're trying to pass binary data, or a large amount of text, you will want to pass it over a pipe. 如果您尝试传递二进制数据或大量文本,则将其希望通过管道传递。 The simplest way to do that is to pass it via stdin . 最简单的方法是通过stdin传递它。 But I don't think that's relevant here. 但是我认为这无关紧要。

Third, you're trying to do this inside an asynchronous network client or server. 第三,您尝试在异步网络客户端或服务器中执行此操作。 So, you can't just run another script and block until it's finished, unless you're absolutely sure that it's going to finish very fast. 因此,除非完全确定它将很快完成,否则您不能只运行另一个脚本并阻塞直到它完成。 If your server framework has a way to integrate subprocess es into it (Twisted is the only one I've ever used that does, but there may be others), great. 如果您的服务器框架具有将subprocess进程es集成到其中的方法(Twisted是我曾经使用过的唯一方法,但是可能还有其他方法),那就太好了。 You can fake it if you can toss the process's stdout pipe into your framework's event loop (basically, if you don't care about Windows, and your framework has a way to add a file to the reactor). 如果您可以将流程的stdout管道扔到框架的事件循环中,则可以伪造它(基本上,如果您不关心Windows,并且您的框架可以将文件添加到反应堆中,则可以)。 But otherwise, you will have to use a thread. 但是否则,您将必须使用线程。

I'm assuming you don't need to get any results from the other script, or even know when it's done. 我假设您不需要从其他脚本获得任何结果,甚至不需要知道何时完成。 If that's not true, it gets a bit more complicated. 如果那不是真的,那就变得更加复杂了。

Putting it all together: 放在一起:

def on_message(self, headers, message):
    print 'received a message %s' % message
    obj = json.loads(message)
    detectedimsi = obj["imsi"]
    print detectedimsi
    thread = threading.Thread(target=subprocess.call, 
                              args=[[sys.executable, 'otherscript.py', detectedimsi]])
    thread.daemon = True
    thread.start()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM