Python 如何从用户获取文件路径,然后将其传递到函数(argparse)

Python 如何从用户获取文件路径,然后将其传递到函数(argparse),python,python-3.x,user-input,argparse,Python,Python 3.x,User Input,Argparse,我正在编写一个程序,对文件的内容执行不同的功能。此时,文件存储在变量中,并按如下方式传递给每个函数: file = "path/to/file" 我想做的是允许用户使用我设置的命令行函数输入路径,并将其传递给我的函数 但是,我不确定如何在我这里的命令行文件中实现这一点 cli.py 导入操作系统,argparse 从…起导入解析 def validate_文件(文件名): 如果不存在os.path.exists(文件名): raise argparse.ArgumentTypeError(“{

我正在编写一个程序,对文件的内容执行不同的功能。此时,文件存储在变量中,并按如下方式传递给每个函数:

file = "path/to/file"
我想做的是允许用户使用我设置的命令行函数输入路径,并将其传递给我的函数

但是,我不确定如何在我这里的命令行文件中实现这一点

cli.py

导入操作系统,argparse
从…起导入解析
def validate_文件(文件名):
如果不存在os.path.exists(文件名):
raise argparse.ArgumentTypeError(“{0}不存在”。格式(文件名))
返回文件名
def转储(文件名):
对于parse.uniprot_记录中的记录(文件名):
打印(记录)
...
(更多函数定义)
...
def cli():
#创建一个新的解析器
parser=argparse.ArgumentParser(description=“UniProt Analysis”)
#输入文件
parser.add_参数(“-i”,“--input”,dest=“filename”,type=validate_file,required=True,help=“输入文件”,metavar=“文件”)
subparsers=parser.add_subparsers(help=“输入一个参数以运行函数”)
#添加子parser
subparsers.add_解析器(“dump”,help=“prints all records”)。设置_默认值(func=dump)
#解析命令行
args=parser.parse_args()
打印(类型(args.filename))
#取func参数,它指向我们的函数并调用它
args.func(args)
因此,我希望能够传递文件,并在命令行中具有我希望对其执行的功能,例如。
pipenv运行python program.py path/to/file dump

编辑:已向解析器添加参数以获取用户的输入文件。然后将该文件传递到
dump
函数中,该函数将该文件传递到该函数中:

parse.py

导入gzip
来自Bio import SeqIO
def uniprot_记录(f):
记录=[]
句柄=gzip.open(f)
对于SeqIO.parse(句柄,“uniprot xml”)中的记录:
记录。追加(记录)
退货记录
我的主函数位于一个单独的模块中,它只调用
cli
函数。当我尝试通过执行
pipenv run python uniplot.py-I path/to/file dump
来运行此命令时,它会给出以下错误:

uniprot_记录中的文件“/Users/john/workspace/practical-2/uniplot/parse.py”,第24行 handle=gzip.open(文件位置)

文件“/usr/local/ceral/python/3.7.5/Frameworks/python.framework/Versions/3.7/lib/python3.7/gzip.py”,第57行,打开 raise TypeError(“文件名必须是str或字节对象或文件”)

TypeError:文件名必须是str或bytes对象或文件


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
解析器添加参数。这些将作为对象传递给被调用函数:

import argparse
def转储(args):
打印(参数路径)
def cli():
#创建一个新的解析器
parser=argparse.ArgumentParser()
subparsers=parser.add_subparsers()
parser.add_参数(“path”)
#添加子parser
subparsers.add_解析器(“dump”).set_默认值(func=dump)
#解析命令行
args=parser.parse_args()
#取func参数,它指向函数并调用它
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循环。
我希望这会有所帮助。

现在看起来您并不是将文件名作为函数参数传递-
dump
没有参数,例如-
依赖于全局命名空间中的文件名。我会跟随@sanjusci的答案,但也会让你的函数以文件名为参数。是的,这是有道理的。我将尝试实现它。好的,我已经取得了一些进展。但仍然让我困惑的是,如何将filename作为参数传递给子parser中的其他函数?你是什么意思
args.func(args)
实际上是将所有的
args
传递给被调用的函数(例如
dump
)。鉴于您的代码如上所述,我希望在尝试将参数传递给
dump
时会抛出一个错误,而该错误不需要任何参数。假设所有函数都采用相同参数(单个文件名)的一个示例是执行
args.func(args.filename)
其中定义了
dump
def dump(filename):
然后使用
文件名
在当前使用
文件的转储文件中
OK,这似乎可以将文件传递给函数。然而,现在我得到了一个类型错误:文件名必须是str或bytes对象,或者是一个文件。。。处理该文件的方法是使用gzip解压该文件,我认为通过命令行传递该文件将是一个简单的过程。。。