首页 > 解决方案 > 如何从用户获取文件路径然后传递给函数(argparse)

问题描述

我正在编写一个对文件内容执行不同功能的程序。目前,该文件存储在一个变量中并传递给每个函数,如下所示:

file = "path/to/file"

我想要做的是允许用户使用我设置的命令行函数输入路径并将其传递给我的函数。

但是我不确定如何将它实现到我在这里的命令行文件中

剪辑.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函数,该函数将文件传递给该函数:

解析.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 行,在 open raise TypeError("filename must be a str或字节对象,或文件")

TypeError: filename must be a str or bytes object, or a file

dump使用 gzip 解压缩后,应该简单地打印出给定文件的全部内容。

标签: pythonpython-3.xuser-inputargparse

解决方案


请使用以下语法。

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)

推荐阅读