我正在编写一个对文件内容执行不同功能的程序。目前,文件存储在变量中并传递给每个函数,如下所示:
file = "path/to/file"
我想做的是允许用户使用我设置的命令行函数输入路径并将其传递给我的函数。
但是我不确定如何在我这里的命令行文件中实现它
cli.py
import os, argparse
from . import parse
def validate_file(filename):
if not os.path.exists(filename):
raise argparse.ArgumentTypeError("{0} does not exist".format(filename))
return filename
def dump(filename):
for record in parse.uniprot_records(filename):
print(record)
...
(more function definitions)
...
def cli():
# Create a new parser
parser = argparse.ArgumentParser(description="UniProt Analysis")
# Input file
parser.add_argument("-i", "--input", dest="filename", type=validate_file, required=True, help="enter input file", metavar="FILE")
subparsers = parser.add_subparsers(help="Enter one of the arguments to run function")
# Add subparsers
subparsers.add_parser("dump", help="prints all records").set_defaults(func=dump)
# Parse the command line
args = parser.parse_args()
print(type(args.filename))
# Take the func argument, which points to our function and call it
args.func(args)
所以我希望能够传递文件,并在命令行中拥有我想对其执行的功能,例如pipenv run python program.py path/to/file dump
编辑:已向解析器添加参数以获取用户的输入文件。然后将此文件传递到dump
函数中,该函数将文件传递到此函数中:
parse.py
import gzip
from Bio import SeqIO
def uniprot_records(f):
records = []
handle = gzip.open(f)
for record in SeqIO.parse(handle, "uniprot-xml"):
records.append(record)
return records
我的主要函数在一个单独的模块中,它只是调用cli
函数。当我尝试通过执行pipenv run python uniplot.py -i path/to/file dump
来运行它时,它给了我以下错误:
文件 "/Users/john/workspace/practical -2/uniplot/parse.py",第 24 行,uniprot_records 句柄 = gzip.open(file_location(
文件 "/usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/gzip.py",第 57 行,打开 raise TypeError("文件名必须是 str 或字节对象,或文件"(
类型错误:文件名必须是 str 或字节对象,或文件
dump
应该在使用 gzip 解压缩给定文件后简单地打印出给定文件的全部内容。
请使用以下语法。
import argparse, os
from argparse import ArgumentParser
def validate_file(f):
if not os.path.exists(f):
# Argparse uses the ArgumentTypeError to give a rejection message like:
# error: argument input: x does not exist
raise argparse.ArgumentTypeError("{0} does not exist".format(f))
return f
if __name__ == "__main__":
parser = ArgumentParser(description="Read file form Command line.")
parser.add_argument("-i", "--input", dest="filename", required=True, type=validate_file,
help="input file", metavar="FILE")
args = parser.parse_args()
print(args.filename)
您可以使用parser.add_argument
向parser
添加参数。这些将作为命名空间对象传递给被调用的函数:
import argparse
def dump(args):
print(args.path)
def cli():
# Create a new parser
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
parser.add_argument("path")
# Add subparsers
subparsers.add_parser("dump").set_defaults(func=dump)
# Parse the command line
args = parser.parse_args()
# Take the func argument, which points to the function and call it
args.func(args)
cli()
该命令如下所示:
python cli.py dump some/file
至于推荐的执行此操作方法,这将取决于您的用例。通过命令行将所有参数传递给脚本将允许您以某种自动化方式比通过交互式输入更轻松地运行脚本。它还允许您更轻松地在终端中重新运行相同的任务。如果这与你无关,那么这主要是个人喜好的问题。
对于任何需要用户输入的文件,我通常会创建一个解析器函数。 我会通过以下方式做到这一点:
#! /usr/bin/env python
import argparse
import sys
def my_parser():
"""
Creates argument parser.
"""
parser = argparse.ArgumentParser()
# Input File
parser.add_argument('path',
type=str,
help='some help text')
# function name
parser.add_argument('function',
type=str,
help='some help text')
return parser
def main(args=None):
"""
display user input
"""
# Create parser
subparser = my_parser()
# Parse command-line input
args = subparser.parse_args(sys.argv[1:])
print('User path is -> {}'.format(args.path))
print('User function is -> {}'.format(args.function))
if __name__ == "__main__":
main()
1(你可以从用户那里获取路径 2( 他想要执行的函数名称
从命令行中,您可以按以下方式运行它:
python pathtoyourpythonscript filepath functionname
然后在 main 函数中,您可以根据用户输入编写 if else 循环。 我希望这有所帮助。