在主程序中收集数据,然后 运行 一个外部程序来处理收集的数据并使用结果在主程序中绘制

Collect data in main program, then run an external program to process collected data and use result to plot in main

我正在开发一个程序作为收集数据的用户界面,然后使用外部程序对其进行处理,最后,取回结果以在 main 中绘制它们。 我的问题是我无法在不陷入循环的情况下使用正确的导入函数。

为简单起见,我将创建一个虚拟代码来表示我正在做的事情和我的问题:

main.py

import sys,os, math, statistics, re
from multiprocessing import Process,Queue,Pipe
import subprocess

'''---Data input block---'''

print('-----Welcome to mainX-----')
num1=int(input('type number 1:'))
num2=int(input('type number 2:'))

print('choose a tool between adding and multiplying')
tool=input('multiply/add: ')

'''---Data storage block---'''

class Input:

    def __init__(self, point_a, point_b):
        self.data_a=num1
        self.data_b=num2

    def data_a(self):
        return(self.data_a)

    def data_b(self):
        return(self.data_b)

'''---external program block---'''

if tool == 'add':
     Add= subprocess.run(['python',"add.py"], capture_output=True)

if tool == 'multiply':
     Multiply= subprocess.run(['python',"multiply.py"], capture_output=True)

'''---Plotting block---'''

fig = plt.figure(figsize = (7,5))
ax= fig.add_subplot(111)

TK = np.linspace(1,10)

if tool == add:
   ax.plot(TK, addresult, label='This is te result of addition', c='g', linewidth=3)

if tool == multiply:
       ax.plot(TK, multiplyresult, label='This is te result of multiplying', c='g', linewidth=3)



ax.set_xlim(270, 400)
plt.legend(fontsize=14)
plt.tight_layout()
plt.show()

Add.py

from main import data_a

addresult:[data_a +1, data_a +2, data_a +3]

Multiply.py

from main import data_b
multiplyresult: [data_b *1, data_b *2, data_b *3]

免责声明:此伪代码中显然存在一些错误,但我只是想说明一般流程。

我得到的错误是:

ImportError: cannot import name 'data_a' from 'main'

或者只是进入一个无限循环请求输入数据

感谢您的帮助!

这段代码有很多错误。

没有data_adata_b,只有self.data_aself.data_b

您创建了 class Input 但您从未创建过

这样的实例
data = Input(num1, num2)

将数据保存在此class。

但这一切都是无用的,因为 self.data_a self.data_a 是在内存中动态创建的,当您 运行 main.pyimport main 只能从文件加载代码main.py - 它无法获取在 main 为 运行ning 时创建的数据。您必须将数据保存在文件中,而其他脚本必须从文件中读取。或者您必须在命令行 run(['python',"multiply.py", str(num1)] 中将其作为参数发送,而其他脚本必须使用 sys.argv[1] 来获取它。并且脚本必须使用 print() 将结果发送回 main (subprocess)。 main 必须读取此字符串,拆分为分隔的数字并转换为整数 - 因此需要大量工作。

还有其他问题。当您导入 main 时,它会 运行 包含此文件中不在函数中的所有代码 - 因此您有循环再次询问输入。

我会用不同的方式来做。我会将代码放在 Add.pyMultiply.py 中的函数中,我会 import Add, Multiply 中的 main。这样我就可以 运行 它没有 subprocess

像这样

Add.py

def add(data):
    return [data+1, data+2, data+3]

Multiply.py

def multiply(data)
    return [data*1, data*2, data*3]

main.py

import sys  # PEP8: imports in separated lines
import os
import math
import statistics
import re

from Add import add
from Multiply import multiply

# --- classes ---

class Input:

    def __init__(self, a, b):
        self.a = a
        self.a = b

    def get_a(self):
        return self.a

    def get_b(self):
        return self.b

# --- functions ---

def main():
    # ---Data input block---
    
    print('-----Welcome to mainX-----')
    num1 = int(input('type number 1:'))  # PEP8: spaces aroung `=`
    num2 = int(input('type number 2:'))
    
    print('choose a tool between adding and multiplying')
    tool = input('multiply/add: ')
    
    # ---Data storage block---
    
    data = Input(num1, num2)
    
    # ---external program block---
    
    if tool == 'add':
         result = add(data.get_a())
    
    if tool == 'multiply':
         result = multiply(data.get_b())
    
    # ---Plotting block---
    
    fig = plt.figure(figsize=(7,5))  
    ax = fig.add_subplot(111)
    
    TK = np.linspace(1,10)
    
    if tool == 'add':
        ax.plot(TK, result, label='This is te result of addition', c='g', linewidth=3)
    
    if tool == 'multiply':
        ax.plot(TK, result, label='This is te result of multiplying', c='g', linewidth=3)
    
    ax.set_xlim(270, 400)
    plt.legend(fontsize=14)
    plt.tight_layout()
    plt.show()
    
if __name__ == '__main__':
    main()

编辑:

subprocess 看起来像这样

Add.py

import sys

if len(sys.argv) > 1
    data = int(sys.argv[1])
    print(data+1, data+2, data+3)

Multiply.py

import sys

if len(sys.argv) > 1
    data = int(sys.argv[1])
    print(data*1, data*2, data*3)

main.py

import sys  # PEP8: imports in separated lines
import os
import math
import statistics
import re
import subprocess

# --- classes ---

class Input:

    def __init__(self, a, b):
        self.a = a
        self.a = b

    def get_a(self):
        return self.a

    def get_b(self):
        return self.b

# --- functions ---

def main():
    # ---Data input block---
    
    print('-----Welcome to mainX-----')
    num1 = int(input('type number 1:'))  # PEP8: spaces aroung `=`
    num2 = int(input('type number 2:'))
    
    print('choose a tool between adding and multiplying')
    tool = input('multiply/add: ')
    
    # ---Data storage block---
    
    data = Input(num1, num2)
    
    # ---external program block---
    
    if tool == 'add':
         p = subprocess.run(['python', 'Add.py', str(data.get_a())])
    
    if tool == 'multiply':
         p = subprocess.run(['python', 'Multiply.py', str(data.get_b())])
    
    output = p.stdout
    result = [int(value) for value in output.split(' ')]

    # ---Plotting block---
    
    fig = plt.figure(figsize=(7,5))  
    ax = fig.add_subplot(111)
    
    TK = np.linspace(1,10)
    
    if tool == 'add':
        ax.plot(TK, result, label='This is te result of addition', c='g', linewidth=3)
    
    if tool == 'multiply':
        ax.plot(TK, result, label='This is te result of multiplying', c='g', linewidth=3)
    
    ax.set_xlim(270, 400)
    plt.legend(fontsize=14)
    plt.tight_layout()
    plt.show()
    
if __name__ == '__main__':
    main()

正如 @furas 所建议的那样,完成这项工作的最佳方法是将输入保存在 main 中,在外部脚本中定义方法,然后将它们导入 main 将它们与输入信息一起使用。 您也可以将结果保存在 main 中,然后将其用于任何您想要的。喜欢密谋。

为了补充 @furas 编写的代码并使其功能齐全,我做了一些小的调整:

Add.py

def add(data):
    return [data+1, data+2, data+3]

Multiply.py

def multiply(data):
    return [data*1, data*2, data*3]

main.py

import sys  # PEP8: imports in separated lines
import os
import math
import statistics
import re
import numpy as np
import matplotlib.pyplot as plt


from Add import add
from Multiply import multiply


# --- classes ---

class Input:

    def __init__(self, a, b):
        self.a = a
        self.b = b

    def get_a(self):
        return self.a

    def get_b(self):
        return self.b

# --- functions ---

def main():
    # ---Data input block---

    print('-----Welcome to mainX-----')
    num1 = int(input('type number 1:'))  # PEP8: spaces aroung `=`
    num2 = int(input('type number 2:'))

    print('choose a tool between adding and multiplying')
    tool = input('multiply/add: ')

    # ---Data storage block---

    data = Input(num1, num2)

    # ---external program block---

    if tool == 'add':
         result = add(data.get_a())

    if tool == 'multiply':
         result = multiply(data.get_b())

    # ---Plotting block---

    fig = plt.figure(figsize=(7,5))
    ax = fig.add_subplot(111)

    if tool == 'add':
        ax.plot(result, label='This is the result of addition', c='r', linewidth=3)

    if tool == 'multiply':
        ax.plot(result, label='This is the result of multiplying', c='g', linewidth=3)

    plt.legend(fontsize=14)
    plt.tight_layout()
    plt.show()

if __name__ == '__main__':
    main()