如何扩展此Python脚本以通过命令行接收用户输入而不是提示?

0 投票
2 回答
577 浏览
提问于 2025-04-17 00:12

现在,我有一个Python脚本,它可以读取一个文本文件,检查里面被标签##Somethinghere##包围的段落,并询问用户想要复制多少次这些段落。比如说,如果我的文本文件是:

Random Text File

##RandomLine1##
Random Line 1
##RandomLine1##

Random Line 2

##RandomLine3##
Random Line 2
##RandomLine3##

End of file

然后程序会提示用户:

Loop "RandomLine1" how many times?
Loop "RandomLine3" how many times?

用户输入数字后,程序会按照输入的次数复制那些特定的段落,并去掉标签。复制后的文本会输出到一个指定的文件中。

要启动这个脚本,命令是这样的:

python script.py inputfile outputfile

我想做的是,不再询问用户输入,而是让用户可以选择性地在命令行中输入循环的次数,类似于:

python script.py inputfile outputfile --RandomLine1 2 --RandomLine3 2

这样做在Python脚本中可行吗?我在下面附上当前版本的脚本:

import re
import argparse

pattern = '##([^#]*)##'

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('infile', type=argparse.FileType('r'))
    parser.add_argument('outfile', type=argparse.FileType('w'))
    args = parser.parse_args()

    matcher = re.compile(pattern)
    tagChecker = False
    strList = []
    for line in args.infile:
        if tagChecker is True:
            lineTest = matcher.search(line)
            if lineTest:
                tagChecker = False
                for _ in range(int(raw_input('Loop ' + lineTest.string[2:-3] + ' how many times?')) - 1):
                    for copyLine in strList:
                        args.outfile.write(copyLine)
                new_line = matcher.sub("", line)
                args.outfile.write(new_line)
                strList = []
                continue
            else:
                strList.append(line)
                args.outfile.write(line)
        if tagChecker is False:
            lineTest = matcher.search(line)
            if lineTest:
                tagChecker = True
                new_line = matcher.sub("", line)
                args.outfile.write(new_line)
            else:
                args.outfile.write(line)

    args.infile.close()
    args.outfile.close()

if __name__ == '__main__':
    main()

2 个回答

2

是的,你可以通过给你的参数设置默认值来实现这个功能:

parser.add_argument("--RandomLine1", default=None)
# same for RandomLine2

# ...

if args.RandomLine1 is not None:
    # use args.RandomLine1 as a number
    #...
else:
    # RandomNumber1 is not given in the args
    #...
2

你可以试试用 sys.argv 吗?

sys.argv 会返回一个列表,里面是你脚本接收到的参数,这些参数是用空格分开的。其中 sys.argv[0] 是脚本的名字。

比如说,下面这个程序:

import sys
print sys.argv

如果以这样的方式运行:

python script.py inputfile outputfile --RandomLine1 2 --RandomLine3 2

就会产生以下输出:

['script.py', 'inputfile', 'outputfile', '--RandomLine1', '2', '--Randomline3', '2']

如果你想创建一个字典,把每一行和对应的参数放在一起,可以试试下面这样的代码:

# Get portion of list that isn't the script name or input/output file name
args = sys.argv[3:]
args_dict = {}

i = 0
while i < len(args):
    if args[i].startswith('--'):
        line = args[i].replace('--', '')
        try:
             args_dict[line] = int(arg[i+1])
        except IndexError:
             print "%s has no argument" % line
        i += 1

根据你的输入示例,我们会得到 args_dict == {'RandomLine1': 2, 'RandomLine3': 2}。从这里看,使用这个字典来做你想做的事情应该很简单。

当然,上面的代码可以根据你对输入的可靠性预期,做得更详细或更简单。

撰写回答