验证另一个论点
Validate an argument over another
我有两个额外的选项,我需要先验证第二个选项。
我试过这个:
#!/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 -loc):
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
有人对我有想法或曲目吗?
您可以使用一个字母参数和一个破折号,以及多个字母参数和两个破折号:
-h, --help
如果 /fr
目录不存在,则错误消息有意义。
如果您想要有关使用和退出的错误消息,请使用 parser.error(...)
,而不仅仅是引发异常。
我已经简化了您的代码,部分是为了适应常见的 argparse 用法,但更重要的是专注于正确解析。因为我的 LANG 是 'en',所以我把那部分测试去掉了。此时针对特定目录的测试会分散注意力。
我认为您的主要问题是 type=directory
参数。该参数应该是一个接受字符串和 returns 的函数。它没有指定您想要的对象类型。由于没有 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
我有两个额外的选项,我需要先验证第二个选项。
我试过这个:
#!/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 -loc):
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
有人对我有想法或曲目吗?
您可以使用一个字母参数和一个破折号,以及多个字母参数和两个破折号: -h, --help
如果 /fr
目录不存在,则错误消息有意义。
如果您想要有关使用和退出的错误消息,请使用 parser.error(...)
,而不仅仅是引发异常。
我已经简化了您的代码,部分是为了适应常见的 argparse 用法,但更重要的是专注于正确解析。因为我的 LANG 是 'en',所以我把那部分测试去掉了。此时针对特定目录的测试会分散注意力。
我认为您的主要问题是 type=directory
参数。该参数应该是一个接受字符串和 returns 的函数。它没有指定您想要的对象类型。由于没有 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