验证一个论点

2024-03-29 06:27:08 发布

您现在位置:Python中文网/ 问答频道 /正文

我有两个额外的选择,我需要验证第二个考虑到第一。你知道吗

我试过这个:

#!/bin/env python3
# -*- coding: utf-8 -*-

from argparse import ArgumentParser, ArgumentTypeError
from os import getenv, path

def invalidArgument(value, text= None):
    raise ArgumentTypeError("%s %s" % (value, text))

def directory(value):
    if path.isdir(value):
        return value
    invalidArgument(value, "directory not found")

def parsing():
    parser= ArgumentParser("")
    parser.add_argument("-dir", type= directory, action= "store", default= "/home", help= "Base directory")
    parser.add_argument("-loc", action= "store_true", help= "Takes into account locale")
    namespace, other= parser.parse_known_args()
    if namespace.loc:
        l= getenv("LANG", "en")[0:2].lower()
        if l == "en":
            namespace.loc= False
        else:
            if path.isdir(path.join(namespace.dir, l)):
                namespace.loc= path.join(namespace.dir, l)
            else:
                invalidArgument(path.join(namespace.dir, l), "directory not found $LANG not valid")
    return namespace, other

if __name__ == "__main__":
    namespace, other= parsing()
    print("Base directory:", namespace.dir)
    print("Locale directory:", namespace.loc)

而我得到了/tst.py公司-地址):

Traceback (most recent call last):
  File "./tst.py", line 32, in <module>
    namespace, other= parsing()
  File "./tst.py", line 28, in parsing
    invalidArgument(path.join(namespace.dir, l), "directory not found or $LANG not valid")
  File "./tst.py", line 8, in invalidArgument
    raise ArgumentTypeError("%s %s" % (value, text))
argparse.ArgumentTypeError: /usr/share/fr directory not found $LANG not valid

如果我打电话给:

./tst.py

我需要:

Base directory: /home
Locale directory: False

如果我打电话给:

./tst.py -loc

我需要:

Base directory: /home
Locale directory: /home/fr

如果我打电话给:

./tst.py -dir=/home/foo -loc

我需要:

Base directory: /home/foo
Locale directory: /home/foo/fr

有人对我有什么想法或线索吗?你知道吗


Tags: pathpyhomebaseifvaluedirnot
3条回答

如果/fr目录不存在,则错误消息是有意义的。你知道吗

如果您想要一个带有usage和exit的错误消息,请使用parser.error(...),而不仅仅是引发异常。你知道吗

我已经简化了您的代码,部分是为了适应常见的argparse用法,但更重要的是要集中精力正确解析。因为我的语言是“恩”,所以我参加了那部分测试。在这一点上,测试特定目录是一种干扰。你知道吗

我认为您的主要问题是type=directory参数。这个参数应该是一个函数,它接受一个字符串并返回所需的内容。它没有指定您想要的对象类型。由于没有directory(astr)函数,这一步就失败了。你知道吗

def parsing():
    parser= ArgumentParser(prog='PROG')
    parser.add_argument('-d'," dir", default= "/home", help= "Base directory")
    parser.add_argument('-l'," loc", action= "store_true", help= "Takes into account locale")
    namespace, other= parser.parse_known_args()

    if namespace.loc:
        l = 'fr'
        namespace.loc= path.join(namespace.dir, l)
    return namespace, other

各种测试包括:

1139:~/mypy$ python3 stack29283397.py
Base directory: /home
Locale directory: False
1144:~/mypy$ python3 stack29283397.py -l
Base directory: /home
Locale directory: /home/fr
1144:~/mypy$ python3 stack29283397.py  dir=/home/foo -l
Base directory: /home/foo
Locale directory: /home/foo/fr

loc测试更改为:

if namespace.loc:
    l = 'fr'
    namespace.loc= path.join(namespace.dir, l)
    parser.error('%s directory not found'%namespace.loc)

产生:

1145:~/mypy$ python3 stack29283397.py  dir=/home/foo -l
usage: PROG [-h] [-d DIR] [-l]
PROG: error: /home/foo/fr directory not found

如果您想保留type=directory,那么您需要找到或编写具有该名称的函数,例如

def directory(astring):
    # do something to validate this string
    # or transform it into something else
    return astring
class Locale(Action):
    def __init__(self, loc, **kwargs):
        super().__init__(**kwargs)
    def __call__(self, parser, namespace, value= False, option_string= None):
        l= getenv("LANG", "en")[0:2].lower()
        if l != "en":
            if path.isdir(path.join(namespace.dir, l)):
                value= path.join(namespace.dir, l)
            else:
                parser.error("%s %s" % (option_string, "directory not found or $LANG not valid"))
        namespace.loc= value

def parsing():
    parser= ArgumentParser("")
    parser.add_argument("-dir", type= directory, action= "store", default= "/home")
    parser.add_argument("-loc", action= Locale, loc= None, nargs= "?", default= False)
    namespace, other= parser.parse_known_args()
    return namespace, other

可以将一个字母的参数与一个破折号一起使用,将多个字母的参数与两个破折号一起使用: -h、 救命

相关问题 更多 >