2013-10-10 2 views
5

저는 주로 파이썬에서 명령 행 스크립트를 만들기 위해 argparse를 사용했습니다. 일반적으로 사용하는 관용구는 인수를 그런 다음 속성 이름과 일치하는 변수에 개별적으로 구문 분석하십시오. 이것은 약간 반복되는 것처럼 보입니다. 그들 모두를 전역 네임 스페이스에 할당하고 할당 단계를 생략 할 수있는 방법이 있습니까? 또는 일부 파이썬 동작이 나에게 반 직관적 인 것처럼 보이는 경우처럼, 일부 현명한 사람이 파이썬 전문가가 지적한 바에는 이렇게하지 않거나 이렇게하고 싶지 않을 수 있습니다. 나는이 싶은 무엇파이썬은 전역 네임 스페이스에 argparse parse_args를 덧붙입니다. (또는 나쁜 생각입니다.)

if __name__ == "__main__": 
    parser = argparse.ArgumentParser() 
    parser.add_argument("--db",type=str, dest='db', nargs='?', default="test") 
    parser.add_argument("--collection",type=str, dest='collection', nargs='?', help="Collection, default is test", default="test") 
    args = parser.parse_args() 
    db = args.db     # gross! 
    collection = args.collection # yuck! 
    print(db) 
    print(collection) 

은 다음과 같습니다 :

는 내가 지금 가지고있는 것은 이것이다

if __name__ == "__main__": 
    parser = argparse.ArgumentParser() 
    parser.add_argument("--db",type=str, dest='db', nargs='?', default="test") 
    parser.add_argument("--collection",type=str, dest='collection', nargs='?', help="Collection, default is test", default="test") 
    parser.SUPER_parse_args() # now, db and collection are already in the namespace! 
    print(db) 
    print(collection) 

은하지 않는 것처럼 많이 나는 단지 2 개 인자,하지만 난 경우가있을 때 10 개 정도가 있다면 할당 단계가 두 배가됩니다. 여기서 args 객체에 이미 존재하는 속성이 전역 네임 스페이스로 바뀌면 버그가 나기 시작합니다.

+6

하지 마십시오. 그냥 하지마. 대신'args'를 직접 사용하겠습니다. –

+0

@ MartijnPieters, 당신은 정확하게 내가 무게를 달고 싶었던 현명한 파이썬 전문가 중 한 명이었습니다. – Mittenchops

답변

6

당신은 globals를 사용하여이 작업을 수행 할 수 있습니다

globals().update(args.__dict__) 

그러나, 당신이 정말로 * 그렇게해서는 안된다. 파이썬의 선 (zen)에서

네임 스페이스는 훌륭한 아이디어입니다.

은하지 마십시오 : 나는 무엇을 @Martijn 그의 주석에서 말했다 에코거야

. 그냥 하지마. 대신 args을 직접 사용하겠습니다.

가능한 한 멀리 분리하십시오. 코드를 이해하기 쉽고 이해하기 쉽게 만듭니다. mgilson의 대답에 추가하려면

+0

알겠습니다. 고마워. 전역 적으로 변수를 정의하고 args를 벗어나는 변수가 새로운 것과 충돌 할 가능성이 더 큰 것을 의미하는 이유는 무엇입니까? 그렇다면 변수를 전역 범위에서 정의하는 단순한 일회성 파이썬 스크립트보다이 전역 변수를 실제로 업데이트하는 것이 더 좋을까요? 작은 스크립트가 필연적으로 더 똑똑한 네임 스페이스 관리가 필요한 커다란 스크립트로 바뀌는 아이디어입니까? – Mittenchops

+2

@Mittenchops - 그 일부입니다. 또한 소스를 훨씬 쉽게 읽을 수 있습니다. 3 개월 후, 스크립트를 업데이트해야하고 변수'foo'를 사용하여 자신을 보게됩니다. 그러나 소스를 grep하려고 할 때 foo는 정의되어 있지 않습니다. 그런 다음 머리를 긁어 내고 어떻게 생겼는지 궁금합니다. 모든 것이 작동합니다. – mgilson

0

:

대신 locals().update(args.__dict__) 사용을 고려; 이것은 전역 네임 스페이스가 아닌 현재 네임 스페이스를 업데이트합니다.

locals() 또는 vars()를 사용하여이를 수행 할 수도 있습니다. 이 둘의 차이에 대한 좋은 설명은 this Stack Overflow post을 참조하십시오.

나는 Mittonchops에게는 조금 늦었지만, 다른 사람들에게 도움이되기를 바랍니다.

+0

지역 주민을 사용하지 마십시오. 그것은 작동하지 않습니다. :-). 지역 사인을 업데이트하는 것은 파이썬의 구현에 대해서는 보장 할 수 없으며 CPython에서는 작동하지 않습니다 (네임 스페이스 인 locals() == globals() 인 경우 제외) :-) – mgilson

0

이것은 내가 한 행동입니다. 그것은 가변 충돌하지만 유지 보수가 도움이됩니다.

parser_args = parser.parse_args() 
if parser_args.verbose: 
    globals().update(argparse.Namespace(verbose=parser_args.verbose).__dict__) 
관련 문제