我还有两个选项,我需要首先考虑第二个选项。
我试过了:
#!/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
有没有人对我有想法或追踪?
答案 0 :(得分:0)
你可以使用带有一个破折号的oneletter args和带有两个破折号的manyletters args: -h, - help
答案 1 :(得分:0)
如果/fr
目录不存在,则错误消息有意义。
如果您需要包含使用和退出的错误消息,请使用parser.error(...)
,而不是仅提出异常。
我简化了你的代码,部分是为了适应常见的argparse用法,但更重要的是要专注于正确解析。由于我的LANG是'en',我把测试的那一部分拿出去了。在这一点上测试特定目录是一种分心。
我认为您的主要问题是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
答案 2 :(得分:0)
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