argparse를 사용하여 부울 값 구문 분석
"--foo True"또는 "--foo False"로 작성된 부울 명령 행 인수를 구문 분석하기 위해 argparse를 사용하고 싶습니다. 예를 들면 다음과 같습니다.
my_program --my_boolean_flag False
그러나 다음 테스트 코드는 내가 원하는 것을 수행하지 않습니다.
import argparse
parser = argparse.ArgumentParser(description="My parser")
parser.add_argument("--my_bool", type=bool)
cmd_line = ["--my_bool", "False"]
parsed_args = parser.parse(cmd_line)
슬프게도로 parsed_args.my_bool
평가됩니다 True
. 이것은 내가 변경해도의 경우 cmd_line
수 ["--my_bool", ""]
있기 때문에, 놀라게하는, bool("")
에 evalutates False
.
어떻게 구문 분석 argparse 얻을 수 있습니다 "False"
, "F"
그리고 그들의 낮은 경우로 변형 False
?
이전 제안을 사용하지만 "올바른"구문 분석 오류가있는 또 다른 솔루션은 argparse
다음 과 같습니다.
def str2bool(v):
if isinstance(v, bool):
return v
if v.lower() in ('yes', 'true', 't', 'y', '1'):
return True
elif v.lower() in ('no', 'false', 'f', 'n', '0'):
return False
else:
raise argparse.ArgumentTypeError('Boolean value expected.')
이것은 기본값으로 스위치를 만드는 데 매우 유용합니다. 예를 들어
parser.add_argument("--nice", type=str2bool, nargs='?',
const=True, default=False,
help="Activate nice mode.")
내가 사용할 수 있습니다 :
script --nice
script --nice <bool>
여전히 기본값을 사용합니다 (사용자 설정에 따라 다름). 참조 -이 접근 한 (간접적으로 관련) 단점은 'nargs'는 위치 인수를 잡을 수 있다는 것입니다 이 관련 질문 과 이 argparse 버그 리포트를 .
이 작업을 수행하는보다 정식적인 방법은 다음과 같습니다.
command --feature
과
command --no-feature
argparse
이 버전을 잘 지원합니다 :
parser.add_argument('--feature', dest='feature', action='store_true')
parser.add_argument('--no-feature', dest='feature', action='store_false')
parser.set_defaults(feature=True)
물론 실제로 --arg <True|False>
버전을 원한다면 ast.literal_eval
"type"또는 사용자 정의 함수로 전달할 수 있습니다 ...
def t_or_f(arg):
ua = str(arg).upper()
if 'TRUE'.startswith(ua):
return True
elif 'FALSE'.startswith(ua):
return False
else:
pass #error condition maybe?
나는 그러나 상호 배타적 인 그룹과 mgilson의 답변을 추천
당신이 사용할 수 있도록 --feature
하고 --no-feature
동시에.
command --feature
과
command --no-feature
하지만
command --feature --no-feature
스크립트:
feature_parser = parser.add_mutually_exclusive_group(required=False)
feature_parser.add_argument('--feature', dest='feature', action='store_true')
feature_parser.add_argument('--no-feature', dest='feature', action='store_false')
parser.set_defaults(feature=True)
그런 다음 많은 도우미를 설정하려는 경우이 도우미를 사용할 수 있습니다.
def add_bool_arg(parser, name, default=False):
group = parser.add_mutually_exclusive_group(required=False)
group.add_argument('--' + name, dest=name, action='store_true')
group.add_argument('--no-' + name, dest=name, action='store_false')
parser.set_defaults(**{name:default})
add_bool_arg(parser, 'useful-feature')
add_bool_arg(parser, 'even-more-useful-feature')
무엇 type=bool
을 type='bool'
의미 하는지 혼동이있는 것 같습니다 . 하나 (또는 둘 다)가 '함수를 실행 bool()
하거나'부울을 반환 하십시오 '를 의미해야합니까 ? 그것이 의미 type='bool'
하는 것은 아무것도 의미하지 않습니다. add_argument
제공 'bool' is not callable
사용한 경우와 같은 오류 type='foobar'
, 또는 type='int'
.
그러나 argparse
이와 같은 키워드를 정의 할 수있는 레지스트리가 있습니다. action
`action = 'store_true'와 같이 주로 사용됩니다 . 다음과 같이 등록 된 키워드를 볼 수 있습니다.
parser._registries
사전을 표시하는
{'action': {None: argparse._StoreAction,
'append': argparse._AppendAction,
'append_const': argparse._AppendConstAction,
...
'type': {None: <function argparse.identity>}}
많은 작업이 정의되어 있지만 기본 유형 인 한 가지 유형 만 argparse.identity
있습니다.
이 코드는 'bool'키워드를 정의합니다.
def str2bool(v):
#susendberg's function
return v.lower() in ("yes", "true", "t", "1")
p = argparse.ArgumentParser()
p.register('type','bool',str2bool) # add type keyword to registries
p.add_argument('-b',type='bool') # do not use 'type=bool'
# p.add_argument('-b',type=str2bool) # works just as well
p.parse_args('-b false'.split())
Namespace(b=False)
parser.register()
문서화되지 않았지만 숨겨지지 않았습니다. 대부분의 프로그래머 때문에 그것에 대해 알 필요가 없습니다 type
및 action
테이크 기능과 클래스 값. 둘 다에 대한 사용자 정의 값을 정의하는 많은 스택 오버 플로우 예제가 있습니다.
이전 논의에서 명확 bool()
하지 않은 경우 '문자열 구문 분석'을 의미하지 않습니다. 파이썬 문서에서 :
bool (x) : 표준 진리 테스트 절차를 사용하여 값을 부울로 변환합니다.
이것과 대조
int (x) : 숫자 또는 문자열 x를 정수로 변환합니다.
짧막 한 농담:
parser.add_argument('--is_debug', default=False, type=lambda x: (str(x).lower() == 'true'))
다음은 기본값을 설정하기 위해 추가 행이없는 다른 변형입니다. 부울은 항상 사전 점검없이 논리 문에서 사용될 수 있도록 지정된 값을 갖습니다.
import argparse
parser = argparse.ArgumentParser(description="Parse bool")
parser.add_argument("--do-something", default=False, action="store_true" , help="Flag to do something")
args = parser.parse_args()
if args.do_something:
print("Do something")
else:
print("Don't do something")
print("Check that args.do_something=" + str(args.do_something) + " is always a bool")
나는 같은 문제를 찾고 있었고 예쁜 해결책은 다음과 같습니다.
def str2bool(v):
return v.lower() in ("yes", "true", "t", "1")
위의 제안대로 문자열을 부울로 구문 분석하는 데 사용합니다.
@mgilson는 말뿐만 아니라, 또한 거기에 주목해야한다 ArgumentParser.add_mutually_exclusive_group(required=False)
사소한 것을 적용 할 수 있도록 할 방법 --flag
과 --no-flag
동시에 사용되지는.
비슷한 방법으로 사용하십시오 :
feature.add_argument('--feature',action='store_true')
명령에 --feature 인수를 설정하면
command --feature
type --feature를 설정하지 않으면 인수의 기본값은 항상 False입니다!
이것은 내가 기대하는 모든 것에 적용됩니다.
add_boolean_argument(parser, 'foo', default=True)
parser.parse_args([]) # Whatever the default was
parser.parse_args(['--foo']) # True
parser.parse_args(['--nofoo']) # False
parser.parse_args(['--foo=true']) # True
parser.parse_args(['--foo=false']) # False
parser.parse_args(['--foo', '--nofoo']) # Error
코드:
def _str_to_bool(s):
"""Convert string to bool (in argparse context)."""
if s.lower() not in ['true', 'false']:
raise ValueError('Need bool; got %r' % s)
return {'true': True, 'false': False}[s.lower()]
def add_boolean_argument(parser, name, default=False):
"""Add a boolean argument to an ArgumentParser instance."""
group = parser.add_mutually_exclusive_group()
group.add_argument(
'--' + name, nargs='?', default=default, const=True, type=_str_to_bool)
group.add_argument('--no' + name, dest=name, action='store_false')
더 간단한 방법은 다음과 같이 사용하는 것입니다.
parser.add_argument('--feature', type=lambda s: s.lower() in ['true', 't', 'yes', '1'])
class FlagAction(argparse.Action):
# From http://bugs.python.org/issue8538
def __init__(self, option_strings, dest, default=None,
required=False, help=None, metavar=None,
positive_prefixes=['--'], negative_prefixes=['--no-']):
self.positive_strings = set()
self.negative_strings = set()
for string in option_strings:
assert re.match(r'--[A-z]+', string)
suffix = string[2:]
for positive_prefix in positive_prefixes:
self.positive_strings.add(positive_prefix + suffix)
for negative_prefix in negative_prefixes:
self.negative_strings.add(negative_prefix + suffix)
strings = list(self.positive_strings | self.negative_strings)
super(FlagAction, self).__init__(option_strings=strings, dest=dest,
nargs=0, const=None, default=default, type=bool, choices=None,
required=required, help=help, metavar=metavar)
def __call__(self, parser, namespace, values, option_string=None):
if option_string in self.positive_strings:
setattr(namespace, self.dest, True)
else:
setattr(namespace, self.dest, False)
가장 표준적인 방법은 다음과 같습니다.
parser.add_argument('--ensure', nargs='*', default=None)
ENSURE = config.ensure is None
가장 간단한 방법은 선택 을 사용하는 것입니다 .
parser = argparse.ArgumentParser()
parser.add_argument('--my-flag',choices=('True','False'))
args = parser.parse_args()
flag = args.my_flag == 'True'
print(flag)
--my-flag를 전달하지 않으면 False로 평가됩니다. 필요 = 사실 당신은 항상 명시 적으로 선택을 지정하려면 사용자가 원하는 경우에 옵션을 추가 할 수 있습니다.
참고 URL : https://stackoverflow.com/questions/15008758/parsing-boolean-values-with-argparse
'Programming' 카테고리의 다른 글
node.js에서 한 번에 한 줄씩 파일을 읽습니까? (0) | 2020.02.11 |
---|---|
PowerShell에서 문자열과 변수를 어떻게 연결합니까? (0) | 2020.02.11 |
Git의 사인 오프 기능은 무엇입니까? (0) | 2020.02.11 |
require ()와 library ()의 차이점은 무엇입니까? (0) | 2020.02.11 |
함수 / 메소드에 대해 키워드 '인라인'을 언제 작성해야합니까? (0) | 2020.02.11 |