programing

argparse를 사용하여 부울 값 구문 분석

bestcode 2022. 9. 23. 00:21
반응형

argparse를 사용하여 부울 값 구문 분석

argparse를 사용하여 "--foo True" 또는 "--foo False"로 작성된 부울 명령줄 인수를 구문 분석합니다.예를 들어 다음과 같습니다.

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_boolTruecmd_line["--my_bool", ""]놀라운 일이지만, 그 이후로bool("")False.

에서 argparse를 해야 요?"False","F"그은 , , , , , , , , , , , , , , , , , , , , .False

보다 표준적인 방법은 다음과 같습니다.

command --feature

그리고.

command --no-feature

argparse 이 하고 있습니다.

Python 3.9+:

parser.add_argument('--feature', action=argparse.BooleanOptionalAction)

Python < 3 . 9 :

parser.add_argument('--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'무엇보다'...

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?

한 다른 "" 분석 .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 버그 보고서를 참조하십시오.

「」를 --feature ★★★★★★★★★★★★★★★★★」--no-feature

는 셸 를 만들 수 .--feature에 덧씌우다.--no-feature.

Python 3.9 이상

parser.add_argument('--feature', default=True, action=argparse.BooleanOptionalAction)

Python 3.8 이하

나는 mgilson의 대답을 추천한다.

parser.add_argument('--feature', dest='feature', action='store_true')
parser.add_argument('--no-feature', dest='feature', action='store_false')
parser.set_defaults(feature=True)

하지 --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')

다음은 기본값을 설정하기 위한 추가 행/초 없는 다른 변동입니다.부울 값은 항상 할당되므로 사전에 확인하지 않고 논리문에서 사용할 수 있습니다.

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(f"Check that args.do_something={args.do_something} is always a bool.")

oneliner:

parser.add_argument('--is_debug', default=False, type=lambda x: (str(x).lower() == 'true'))

가 잘못됐는지 것 요.type=bool ★★★★★★★★★★★★★★★★★」type='bool'의미할 수 있습니다.중 둘 다)가 '를 실행하라'(둘 다)는요?bool()'어느새'는요? 상태로는type='bool'아무 의미도 없어요 add_argumentgives '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()'어느 정도'는요.Python 서 :

부울(x):표준 진실 테스트 절차를 사용하여 값을 부울로 변환합니다.

이것과 대조하다

int(x): 숫자 또는 문자열x 를 정수로 변환합니다.

비슷한 방법으로 다음을 사용할 수 있습니다.

feature.add_argument('--feature',action='store_true')

명령어로 --internal 인수를 설정한 경우

 command --feature

type --feature를 설정하지 않으면 인수는 True가 됩니다.인수의 기본값은 항상 False입니다.

가장 심플하고 올바른 방법은 다음과 같습니다.

from distutils.util import strtobool

parser.add_argument('--feature', dest='feature', 
                    type=lambda x: bool(strtobool(x)))

True 값은 y, yes, t, true, on 및 1이며 false 값은 n, no, f, false, off 및 0입니다.val이 다른 것일 경우 ValueError를 발생시킵니다.

저도 같은 문제를 찾고 있었는데, 예쁜 해결책은 다음과 같습니다.

def str2bool(v):
  return v.lower() in ("yes", "true", "t", "1")

그리고 그것을 사용하여 위에서 제시한 바와 같이 문자열을 부울로 해석합니다.

이것은 내가 기대하는 모든 것에 유효하다.

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')

@mgilson이 말한 것 외에 그것을 강제하는 것을 하찮게 하는 방법도 있다는 점에 유의해야 합니다.--flag ★★★★★★★★★★★★★★★★★」--no-flag동시에 사용되지 않습니다.

가장 간단합니다.유연하지는 않지만 심플한 것이 좋습니다.

  parser.add_argument('--boolean_flag',
                      help='This is a boolean flag.',
                      type=eval, 
                      choices=[True, False], 
                      default='True')

편집: 입력을 신뢰할 수 없는 경우 사용하지 마십시오.eval.

이건 사실 구식이에요.Python 3.7+의 경우 Argparse는 부울 arg를 지원합니다(검색 Boolean Optional Action).

실장은 다음과 같습니다.

import argparse

ap = argparse.ArgumentParser()

# List of args
ap.add_argument('--foo', default=True, type=bool, help='Some helpful text that is not bar. Default = True')

# Importable object
args = ap.parse_args()

기타 주의사항 : argparse를 통한 인수의 True 및 False 이외의 모든 엔트리가 차단됩니다.논쟁타입 에러어떤 이유로든 이 클래스를 변경하려고 할 경우 이 클래스의 커스텀에러 클래스를 작성할 수 있습니다.

보다 간단한 방법은 다음과 같이 사용하는 것입니다.

parser.add_argument('--feature', type=lambda s: s.lower() in ['true', 't', 'yes', '1'])

앞서 @akash-desarda의 Excellence https://stackoverflow.com/a/59579733/315112에 따라 다음 절차를 수행합니다.strtobool★★★★★★★★★★★★★★★★★를 통해lambda, , , , , , , , , , , , , , , , , , , , , , , , 을 사용하기로 strtobool대신 직접.

import argparse
from distutils import util
parser.add_argument('--feature', type=util.strtobool)

요, 네, 맞아요.strtobool.int, 가 아닙니다.bool.그렇지만strtobool이외의 값은 반환되지 않습니다.0그리고.1, python이 그것들을 변환합니다.bool매끄럽고 일관되게 가치를 부여합니다.

>>> 0 == False
True
>>> 0 == True
False
>>> 1 == False
False
>>> 1 == True
True

다음과 같은 잘못된 입력 값을 수신하는 동안

python yours.py --feature wrong_value

아르파르세.액션:strtobool비교해서lambda에러 메세지가 조금 더 선명하게 표시됩니다.

yours.py: error: argument --feature: invalid strtobool value: 'wrong_value'

이 코드와 비교해서

parser.add_argument('--feature', type=lambda x: bool(util.strtobool(x))

그러면 다음과 같은 오류 메시지가 나타납니다.

yours.py: error: argument --feature: invalid <lambda> value: 'wrong_value'

가장 간단한 방법은 선택지를 사용하는 것입니다.

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로 평가됩니다.필요한 =True 옵션은 사용자가 항상 명시적으로 선택 항목을 지정하도록 하는 경우 추가할 수 있습니다.

@Akash Desarda의 답변에 대한 개선사항으로 다음을 수행할 수 있습니다.

import argparse
from distutils.util import strtobool

parser = argparse.ArgumentParser()
parser.add_argument("--foo", 
    type=lambda x:bool(strtobool(x)),
    nargs='?', const=True, default=False)
args = parser.parse_args()
print(args.foo)

아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아.python test.py --foo

(base) [costa@costa-pc code]$ python test.py
False
(base) [costa@costa-pc code]$ python test.py --foo 
True
(base) [costa@costa-pc code]$ python test.py --foo True
True
(base) [costa@costa-pc code]$ python test.py --foo False
False

가장 표준적인 방법은 다음과 같습니다.

parser.add_argument('--ensure', nargs='*', default=None)

ENSURE = config.ensure is None

쉽고 빠르게, 단 인수 0 또는1의 경우에만:

parser.add_argument("mybool", default=True,type=lambda x: bool(int(x)))
myargs=parser.parse_args()
print(myargs.mybool)

단말기에서 호출한 후 출력은 "False"가 됩니다.

python myscript.py 0

파라미터의 기본값을 False로 저장하는 좋은 방법을 찾았습니다.이 파라미터가 명령줄 인수에 존재할 경우 파라미터의 값은 true여야 합니다.

인수를 true로 하는 경우의 cmd 명령: python main.py --csv

python main 인수가 false여야 합니다.화이

import argparse
from ast import parse
import sys
parser = argparse.ArgumentParser(description='')
parser.add_argument('--csv', action='store_true', default = False 
,help='read from csv')
args = parser.parse_args()

if args.csv:
    print('reading from csv')
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)

@Akash와 비슷하지만 제가 사용한 다른 접근법이 있습니다. it it를 한다.strlambda python은 python을 위해서lambda항상 외계인처럼 느껴져요

import argparse
from distutils.util import strtobool

parser = argparse.ArgumentParser()
parser.add_argument("--my_bool", type=str, default="False")
args = parser.parse_args()

if bool(strtobool(args.my_bool)) is True:
    print("OK")

'다음에 하다', '다음에 하다', '다음에 하다' 이렇게 수 요.--test = True

python filename --test

parser.add_argument("--test" , default=False ,help="test ?", dest='test', action='store_true')

값 변환:

def __arg_to_bool__(arg):
    """__arg_to_bool__

        Convert string / int arg to bool
    :param arg: argument to be converted
    :type arg: str or int
    :return: converted arg
    :rtype: bool
    """
    str_true_values = (
        '1',
        'ENABLED',
        'ON',
        'TRUE',
        'YES',
    )
    str_false_values = (
        '0',
        'DISABLED',
        'OFF',
        'FALSE',
        'NO',
    )

    if isinstance(arg, str):
        arg = arg.upper()
        if arg in str_true_values:
            return True
        elif arg in str_false_values:
            return False

    if isinstance(arg, int):
        if arg == 1:
            return True
        elif arg == 0:
            return False

    if isinstance(arg, bool):
        return arg

    # if any other value not covered above, consider argument as False
    # or you could just raise and error
    return False

[...]


args = ap.parse_args()
my_arg = options.my_arg
my_arg = __arg_to_bool__(my_arg)

Gerardw의 답변을 확대하다

★★parser.add_argument("--my_bool", type=bool)bool("mystring")True이 아닌 의 문자열에 는, 「」를 참조해 주세요.bool("False")는 ★★★★True.

네가 원하는 건

my_program.화이

import argparse

parser = argparse.ArgumentParser(description="My parser")

parser.add_argument(
        "--my_bool",
        choices=["False", "True"],
        )

parsed_args = parser.parse_args()

my_bool = parsed_args.my_bool == "True"

print(my_bool)
$ python my_program.py --my_bool False
False

$ python my_program.py --my_bool True
True

$ python my_program.py --my_bool true
usage: my_program.py [-h] [--my_bool {False,True}]
my_program.py: error: argument --my_bool: invalid choice: 'true' (choose from 'False', 'True')

언급URL : https://stackoverflow.com/questions/15008758/parsing-boolean-values-with-argparse

반응형