从命令行的用户那里获取输入,并使用该输入将变量提供给Python脚本

时间:2016-10-16 21:55:35

标签: python batch-file

我有一个名为GetStats.py的脚本。

在较高级别,GetStats.py脚本执行以下操作:

1)建立与外部数据库的连接 2)从该数据库中检索一些数据 3)将步骤2中检索到的数据写入csv文件

重要的是,GetStats.py脚本引用了一个配置(.cfg)文件,其中包括(在许多其他详细信息中)要连接的特定数据库的IP地址和服务器详细信息。

GetStats.py脚本要求用户在命令行上传递以下参数:

a)要检索的数据天数(即回顾期) b)数据的粒度(每小时或每天) c)是否包括一组有限的数据(运行大约需要30分钟)或整套数据(运行大约需要1小时15分钟)

我还有一个用于运行所有内容的批处理文件。批处理文件如下所示:

GetStats.py Client_A.cfg 30 -d -full
GetStats.py Client_B.cfg 30 -d -full
GetStats.py Client_C.cfg 30 -d -full
GetStats.py Client_D.cfg 30 -d -full
GetStats.py Client_E.cfg 30 -d -full
... and so on up to Client_M

正如我们从上面的批处理文件中看到的那样,GetStats.py脚本被调用,它通过Client_E针对Client_A运行30天,每日粒度并返回完整的数据集。

问题是,如果我想更改任何这些参数(例如,更改回溯期的天数,数据粒度和/或要返回的数据集),我需要编辑批处理文件直接,该过程可能需要几分钟。

我希望简化流程,以便在运行批处理文件后,在命令行中提示用户输入以下

"请输入回顾的天数:"

"请输入数据的粒度:"

"请输入要返回的数据集:"

我已经考虑过如何将这三个参数直接合并到GetStats.py脚本中。

但是,我认为我会遇到问题,因为批处理文件将运行GetStats.py脚本,然后提示用户输入上面的3个参数调用GetStats.py脚本(目前是13次)。

我不希望用户必须输入" 30"," -d"和" -full"共13次。我希望用户输入" 30"," -d"和" -full" 只有一次

有没有人有任何想法如何在批处理文件运行后如何提示用户输入上述3个参数

谢谢!

1 个答案:

答案 0 :(得分:0)

考虑将 GetStats.py 作为模块用于另一个.py脚本,该脚本通过input()(或Python 2中的raw_input())接收用户输入。这样,您就不需要批处理文件或通过命令行输入参数,这不是用户友好的界面。此外,您可以使用string.ascii_uppercase遍历所有客户端类型以获取DRY-er方法。以下是设置:

GetStats.py

(将整个脚本包装在接收先前通过命令行发送的参数的已定义模块中,不再是sys.argv[]集合)

def processData(clienttype, lookbackdaysparam, granularityparam, datasettypeparam):
   #...script...

UserInput.py

(与GetStats.py放在同一目录中;考虑控制数字/字符串值)

import GetStats
from string import ascii_uppercase

lookbackdays = ''; granularity = ''; datasettype = ''

# LOOP RUNS INFINITELY PROMPTING INPUT UNTIL USER FILLS OUT EACH ONE:
while True:    
    if lookbackdays == '':
        lookbackdays = input("Please enter the number of days to look back: ")

    elif granularity == '':
        granularity = input("Please enter the granularity of the data: ")

    elif datasettype == '':
        datasettype = input("Please enter the data set to return: ")

    else:
        break

# LOOPS THROUGH LETTERS A-M
for c in ascii_uppercase[0:13]:
    GetStats.processData('Client_'+c+'.cfg', lookbackdays, granularity, datasettype)

print("Successfully processed data!")

Tkinter GUI

更好的是,考虑使用tkinter模块(在Python 3中预安装)的实际GUI界面:

import GetStats
from tkinter import *
from tkinter import ttk 
from string import ascii_uppercase

class GUIapp():

    def __init__(self):
        self.root = Tk()
        self.buildControls()
        self.root.mainloop()

    def buildControls(self):        
        self.root.wm_title("Get Stats Menu")
        self.guiframe = Frame(self.root, width=2500, height=500, bd=1, relief=FLAT)
        self.guiframe.pack(padx=5, pady=5)

        # IMAGE
        self.photo = PhotoImage(file="Stats.png")
        self.imglbl = Label(self.guiframe, image=self.photo)
        self.imglbl.photo = self.photo
        self.imglbl.grid(row=0, sticky=W, padx=5, pady=5)
        self.imglbl = Label(self.guiframe, text="Enter parameters for data request",
                            font=("Arial", 12)).\
                            grid(row=0, column=1, sticky=W, padx=5, pady=5)

        # PERIOD DAYS 
        self.periodDayslbl = Label(self.guiframe, text="Please enter the number of days to look back: ",
                                  font=("Arial", 10)).grid(row=1, sticky=W, padx=5, pady=5)
        self.periodDaysvar = StringVar()
        self.periodDaystxt = Entry(self.guiframe, textvariable=self.periodDaysvar,
                                  relief=SOLID, font=("Arial", 10), width=34).\
                                  grid(row=1, column=1, sticky=W, padx=5, pady=5)

        # DATA GRANULARITY
        self.granularitylbl = Label(self.guiframe, text="Please enter the granularity of the data: ",
                                font=("Arial", 10)).grid(row=2, sticky=W, padx=5, pady=5)
        self.granularityvar = StringVar()
        self.granularitytxt = Entry(self.guiframe, textvariable=self.granularityvar,
                                relief=SOLID, font=("Arial", 10), width=34).\
                                grid(row=2, column=1, sticky=W, padx=5, pady=5)

        # DATASET TO RETURN
        self.datasetTypelbl = Label(self.guiframe, text="Please enter the data set to return: ",
                                font=("Arial", 10)).grid(row=3, sticky=W, padx=5, pady=5)
        self.datasetTypevar = StringVar()
        self.datasetTypetxt = Entry(self.guiframe, textvariable=self.datasetTypevar, relief=SOLID,
                                font=("Arial", 10), width=34).\
                                grid(row=3, column=1, sticky=W, padx=5, pady=5)

        # PROCESS BUTTON 
        self.btnoutput = Button(self.guiframe, text="PROCESS",
                                font=("Arial", 10), width=25, command=self.processData).\
                                grid(row=4, column=1, sticky=W, padx=10, pady=5)

    def processData(self):
        if self.periodDaysvar.get() != '' and self.granularityvar.get() != '' and self.datasetTypevar.get() != '':    
            for c in ascii_uppercase[0:13]:
                GetStats.processData('Client_'+c+'cfg', self.periodDaysvar.get(), 
                                     self.granularityvar.get(), self.datasetTypevar.get())                   
                messagebox.showinfo("SUCCESFUL OUTPUT", "Successfully processed data!")
        else:
            messagebox.showerror("MISSING FIELD", "Please enter all fields to process request.")

if __name__ == "__main__":
    GUIapp()

GUI 菜单(图片是与脚本在同一目录中名为Stats.png的小图片)

GUI Menu

消息框(在处理按钮上单击调用)

GUI Success Message GUI Error Message