파이썬 argparse.Namespace ()를 사전으로 취급하는 올바른 방법은 무엇입니까?


228

나는 결과를 사용하려면 argparse.ArgumentParser()Namespace기대하는 방법으로, 객체 사전 또는 개체 (참조 매핑 같은 collections.Mapping을 ), 그것을 할 올바른 방법은 무엇입니까?

C:\>python
Python 2.7.3 (default, Apr 10 2012, 23:31:26) [MSC v.1500 32 bit (Intel)] on win
32
Type "help", "copyright", "credits" or "license" for more information.
>>> import argparse
>>> args = argparse.Namespace()
>>> args.foo = 1
>>> args.bar = [1,2,3]
>>> args.baz = 'yippee'
>>> args['baz']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'Namespace' object has no attribute '__getitem__'
>>> dir(args)
['__class__', '__contains__', '__delattr__', '__dict__', '__doc__', '__eq__', '_
_format__', '__getattribute__', '__hash__', '__init__', '__module__', '__ne__',
'__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__
', '__str__', '__subclasshook__', '__weakref__', '_get_args', '_get_kwargs', 'ba
r', 'baz', 'foo']

객체에 "닿아" __dict__속성을 사용하는 것이 적절 합니까?

나는 대답은 전혀 생각하지 않을 것이다 : __dict__인터페이스, 방법에 대한 구현을위한 규칙 냄새,하지만 __getattribute____setattr__또는 __contains__것으로 보인다.

답변:


385

vars ()를 사용하여 네임 스페이스의 사전에 액세스 할 수 있습니다 .

>>> import argparse
>>> args = argparse.Namespace()
>>> args.foo = 1
>>> args.bar = [1,2,3]
>>> d = vars(args)
>>> d
{'foo': 1, 'bar': [1, 2, 3]}

원하는 경우 사전을 직접 수정할 수 있습니다.

>>> d['baz'] = 'store me'
>>> args.baz
'store me'

예, __dict__ 속성에 액세스해도됩니다. 잘 정의되고 테스트되고 보장 된 동작입니다.


1
문서에 "반환 된 사전은 수정해서는 안됩니다. 해당 기호 테이블에 미치는 영향은 정의되어 있지 않습니다."라고 말합니다. 어느 (의 또는 ) 의 동작을 나타낼 있지만 확실하지 않습니다. vars()locals()globals()

2
흠, 사용 vars()과 의 차이점을 실제로 이해하지 못하는 것 같습니다.__dict__
Jason S

21
@delnan 누군가가 문서를 잘못 편집하여 광범위한 훈계를했습니다. 그 후에 문서가 수정되었습니다. docs.python.org/2.7/library/functions.html#vars를 참조하십시오. 읽기 전용 사전 (예 : 로컬 및 클래스 사전 프록시)이있는 특수한 경우가 있지만 나머지 경우는 업데이트 할 수 있습니다. 바르 (OBJ) 호출은 동의어와 OBJ .__ dict__입니다. 의 경우 argparse 네임 스페이스 (인수)을 바르 업데이트 가능한 사전에 직접 액세스를 제공한다.
Raymond Hettinger 2016 년

1
@RaymondHettinger 알았어. 나는 /3/문서 의 버전 (세밀한 검사, 3.1 ~ 3.4 포함) 에서 그 메모를 얻었 으므로 수정 사항이 분명히 누락되었습니다.

8
@ delnan 방금 3.3 및 3.3 문서를 업데이트했습니다. 내일 볼 수 있습니다. 지적 해 주셔서 감사합니다.
Raymond Hettinger 2016 년

64

말의 입에서 직접 :

속성에 대한 dict-like view를 선호하는 경우 표준 Python 관용구를 사용할 수 있습니다 vars().

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo')
>>> args = parser.parse_args(['--foo', 'BAR'])
>>> vars(args)
{'foo': 'BAR'}

— 파이썬 표준 라이브러리, 16.4.4.6. 네임 스페이스 객체


1
여전히 'foo'는 '-'를 그리워합니다. 그것에 대한 아이디어가 있습니까?
user2678074

1
@ user2678074 이것은 쉘 플래그와 일치시키기위한 것입니다. 대시는 파이썬 실행에서 외부에 있습니다.
Erich

vars(args)제공TypeError: 'dict' object is not callable
user5359531

6
@ user5359531 아마도 전역 vars변수를 변수로 덮어 썼을 것입니다 . __builtins__.vars직접 액세스하거나 del vars섀도 잉을 중지 하는 데 사용할 수 있습니다 .
Nick T

@NickT 사소한 수정 : 파이썬 함수는 정적으로 범위가 지정되므로 함수에서 전역 변수를 음영 처리하면 해당 식별자는 할당되기 전이나 후에도 항상 해당 함수 내의 로컬 변수를 참조합니다 del. 모듈 범위에서 del 것이다 "유엔 그림자"내장 명령으로 작동합니다.
augurar

-1

객체에 "도달하여" dict 속성을 사용하는 것이 적절 합니까?

일반적으로 "아니요"라고 말합니다. 그러나 Namespace클래스가 내장 유형에서 상속 할 수 없었을 때 과도하게 설계되었습니다.

다른 한편으로, Namespaceargparse에 대한 작업 중심의 접근 방식을 제시하며, 나는을 잡아야 할 상황을 생각할 수 없지만 __dict__내 상상의 한계는 당신과 다릅니다.


11
__dict__ 속성에 액세스해도됩니다. 검사는 언어의 기본입니다. 이 특성은 이유로 공개되었습니다 :-)
Raymond Hettinger 2016 년

8
그러나 파이썬의 모든 것은 "공개"입니다. 인스턴스에 사용 된 구현 변수와 그것이 제시하는 퍼블릭 인터페이스 사이에는 구별이 없습니다 (선행 된 밑줄 규칙 제외). 특히 사전과 같은 객체에서 인스턴스 메소드 사이의 선과 함수 인 사전 값은 약간 흐릿합니다.
Jason S

명명 된 매개 변수로 인수를 전달하는 경우? do_something(**args.__dict__)
OrangeDog
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.