2017-12-19 5 views
0

스크립트에 대한 구성 이름 지정된 인수가 있습니다. 구성 파일 및/또는 명령 줄에서 제공하고 싶습니다.Python argparse는 구성 파일/dict의 필수 인수입니다.

  • 일부 인수는 이러한
  • 선택적으로 구성 파일에서 읽은 명령 줄에서 값을 오버라이드 (override)하는/기본적으로
  • 필수 요구된다
  • 인수 (구성 파일 또는 명령을 제공하지 않는 경우
  • 는 오류를보고해야 줄)

전에 set_defaults()를 사용하고 있지만 add_arguments(..., required=True)을 사용하면 오류가 발생합니다.

파이썬 2.7에 대한 더 나은 해결책이 있습니까?

from argparse import ArgumentParser 

# this dict will be read from configuration file 
config_args = {'my_argument': 'value from configuration file'} 

parser = ArgumentParser() 
parser.add_argument('--my-argument', dest='my_argument', required=True) 

# use values from configuration file by default 
parser.set_defaults(**config_args) 

# override with command line arguments when provided 
args = parser.parse_args({}) 

이 예제에서는 오류가 발생합니다 :

usage: [-h] --required REQUIRED 
: error: argument --required is required 
+0

'항상 값이 때문에 = TRUE '가 기본값으로 많은 이해가되지 않습니다 필요합니다. – jordanm

+0

'parser.add_argument ('- required', default = "test")와 같은 각 인수에 기본값을 추가 할 수 있습니다. – Stack

+0

'default = "some value"를 사용하면 별도의 파일. –

답변

0

@hpaulj 대답에 따라 코드를 약간 조정했습니다. ArgumentParser를 사용하여 누락 된 인수에 대해 명령 줄 또는 구성 파일에서 제공하는지 여부를 알립니다.

Python27 ArgumentParser는 추가 된 인수 동작에 액세스하기위한 공용 API를 제공하지 않습니다. 그러나 개인 재산은 _actions입니다. 따라서 단순히 parser._actions을 반복하고 구성 파일에서 제공하는 경우 required 속성을 재설정하면 사용 사례에 대한 충분한 해결책이됩니다.

여기에 고정 코드 :

from argparse import ArgumentParser 

# this dict will be read from configuration file 
config_args = {'my_argument': 'value from configuration file'} 

parser = ArgumentParser() 
arg = parser.add_argument('--my-argument', required=True) 

# use values from configuration file by default 
parser.set_defaults(**config_args) 

# Reset `required` attribute when provided from config file 
for action in parser._actions: 
    if action.dest in config_args: 
     action.required = False 

# override with command line arguments when provided 
args = parser.parse_args({}) 
0
In [355]: config_args = {'my_argument': 'value from configuration file'} 
In [356]: parser = argparse.ArgumentParser() 

add_argument는 생성하고 Action 개체를 반환합니다. 의 해당 개체에 대한 참조를 저장하고 그것을 살펴 보자 : 그 defaultNone, store의 기본 기본값임을

In [357]: a1 = parser.add_argument('--my-argument', dest='my_argument', required 
    ...: =True) 
In [358]: a1 
Out[358]: _StoreAction(option_strings=['--my-argument'], dest='my_argument', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None) 

알 수 있습니다. requiredTrue으로 설정됩니다. 또한 (subparsers 용 문서에 도시)의 인수에 나타나지 않는 dest에 값을 설정하는 데 사용될 수

In [359]: parser.set_defaults(**config_args) 
In [360]: a1 
Out[360]: _StoreAction(option_strings=['--my-argument'], dest='my_argument', nargs=None, const=None, default='value from configuration file', type=None, choices=None, help=None, metavar=None) 

set_defaults :

set_defaultsa1.default 값을 변경한다.

인수없이 실행하면 조치가 필요하므로 오류가 발생합니다. 기본값이 있으면이 값이 무시됩니다. 우리 Falserequired 특성을 변경하는 경우

In [361]: parser.parse_args([]) 
usage: ipython3 [-h] --my-argument MY_ARGUMENT 
ipython3: error: the following arguments are required: --my-argument 
An exception has occurred, use %tb to see the full traceback. 

SystemExit: 2 

(a1는 그 속성 범위 내에서 변경 될 수있다. 즉 a1.default 포함하는 객체이다).

In [362]: a1.required 
Out[362]: True 
In [363]: a1.required=False 
In [364]: parser.parse_args([]) 
Out[364]: Namespace(my_argument='value from configuration file') 

구성 값이 나타납니다. 명령 행 값은이를 겹쳐 쓸 수 있습니다.

In [365]: ns = argparse.Namespace(my_argument='foo') 
In [366]: parser.parse_args([], namespace=ns) 
Out[366]: Namespace(my_argument='foo') 

foo 값은 우선 순위가 있기 때문에 액션 기본 또는 set_defaults 값이 사용되지 않습니다

또한 namespace 매개 변수의 기본값을 제공 할 수 있습니다.이 버그/문제에 argparse: does not respect required args pre-populated into namespace

https://bugs.python.org/issue29670

는 사용자가 required 시험을 대체 할 ns에 값의 존재를 원했다. 즉, 그는이 값이 커맨드 라인에서 제공되고있는 것처럼 행동하기를 원합니다. 나의 결론은 변화하는 것이 쉽지 않다는 것이다. 현재 parse_args 구조는 required과 같은 것들에 대한 수정이나 우회를 허용하지 않습니다.

더 나은 테스트를 원하면 default=None을 그대로두고 구문 분석 후에 직접 테스트 해보십시오.

if args.my_argument is None: 
    args.my_argument = 'default from config' 
+0

@hpaulj에 대한 심층 답변을 보내 주셔서 감사합니다! 이것은 제게 일반적인 해결책을 찾기에 충분했습니다. 내 질문에 대답을 추가했습니다. –

관련 문제