sys.argv [x]가 정의되어 있는지 확인


답변:


64

결국 try, except과 테스트 의 차이점은len(sys.argv) 는 그다지 중요하지 않습니다. 둘 다 argparse.

그러나 이것은 저예산 논쟁의 일종으로 나에게 발생합니다.

arg_names = ['command', 'x', 'y', 'operation', 'option']
args = dict(zip(arg_names, sys.argv))

namedtuple기본값 인 with 값 을 생성하는 데 사용할 수도 있습니다 None.

Arg_list = collections.namedtuple('Arg_list', arg_names)
args = Arg_list(*(args.get(arg, None) for arg in arg_names))

에 익숙하지 않은 경우 namedtuple에는 객체처럼 작동하는 튜플 일 뿐이므로 다음을 사용하여 해당 값에 액세스 할 수 있습니다.tup.attribute 구문 대신 구문을tup[0] .

따라서 첫 번째 줄은의 namedtuple각 값에 대한 값 으로 새 유형을 만듭니다 arg_names. 두 번째 줄은 args딕셔너리 의 값을 전달 하며을 사용 get하여 주어진 인수 이름이 사전에 관련 값이 없을 때 기본값을 반환합니다.


저는 파이썬을 점점 더 좋아합니다. 물론 그와 같은 답변과 Stack Overflow 덕분입니다! 안타깝게도 마지막 두 줄에 대한 설명이 없습니다. 나는 초보자에게 좋을 것이라고 믿습니다.
Goujon 2017

2
그것을 사랑하십시오! 이 문제에 대해 내가 본 최고의 솔루션입니다. 다른 사람의 경우 : 1) 'command'가 매번 첫 번째 인수로 전달되고 2) args [0] 등을 사용하여 결과를 호출 할 수 있다는 것이 (newb) 당장 분명하지 않았습니다.
Matt D

이것은 확실히 멋지지만 길이를 테스트하는 것은 무엇입니까?
colorlace

1
@timwiz 나는 argparse를 사용하는 것과 비교할 때만 이야기했습니다. 그래도 요즘에는 오래된 스크립트로 돌아올 때마다 argparse를 사용하지 않았다는 것을 알게되었습니다.
senderle 19

116

길이 확인 sys.argv:

if len(sys.argv) > 1:
    blah = sys.argv[1]
else:
    blah = 'blah'

어떤 사람들은 귀하가 제안한 예외 기반 접근 방식을 선호 try: blah = sys.argv[1]; except IndexError: blah = 'blah'하지만 (예 :), 거의 "확장"되지 않기 때문에 (예 : 2 ~ 3 개의 인수를 받아들이고 싶을 때)별로 좋아하지 않습니다. 그것은 잠재적으로 (당신이 사용하는 경우, 예를 들어 오류를 숨길 수 blah = foo(sys.argv[1])있지만, foo(...)제기 IndexError하는, IndexError무시 될 것이다)를.


1
당신이 그것에 대해 원자 적이라면, 걱정할 것이 없습니다 try, except. 조항이 foo나올 때까지 당신의 주장을 기다리 십시오 else.
senderle 2011 년

3
또한 스케일링에 대해 생각하고 있다면 argparse.
senderle 2011 년

1
argparse에 +1. 내가있어 argparse.py내 명령 줄 모든 프로젝트에.
David Wolever 2011 년

2
@senderle : 물론, 당신이 그것에 대해 부지런하다면 괜찮습니다. 하지만 내 경험상 대부분의 프로그래머는 부지런하지 않고 모든 논리를 try절 에 넣습니다 . 따라서 더 어렵지 않다는 점을 감안할 때 (그리고 IMO는 조금 더 예쁘다) 길이 만 확인하는 것이 좋습니다 (또한 흐름 제어에 예외를 사용하는 것에 대해 소리 치십시오).
David Wolever 2011 년

2
@David, 그래, 나는 당신의 요점을 봅니다. 나는 약간의 try사과입니다. 인정해야합니다. 나는 그것이 때때로 if진술 보다 더 명확하게 내 의도를 표현한다고 느낍니다 .
senderle 2011 년

22

내가 아직 보지 못한 또 다른 방법은 미리 센티넬 값을 설정하는 것입니다. 이 방법은 항상 else명령문 을 제공 할 필요가없는 Python의 지연 평가를 활용 합니다. 예:

startingpoint = 'blah'
if len(sys.argv) >= 2:
  startingpoint = sys.argv[1]

또는 CRAZY 구문을 사용하는 경우 Python의 삼항 연산자를 사용할 수 있습니다 .

startingpoint = sys.argv[1] if len(sys.argv) >= 2 else 'blah'

1
삼항 연산자의 대답은 내 눈이 가장 예쁘다는 것입니다. 나는 내가 관리하는 소프트웨어 중 일부가 Python 2.4에 연결되어 있다는 사실을 조용히 저주하고 있습니다.
Richard Barrell 2012

11

나는 이것을 사용합니다-결코 실패하지 않습니다.

startingpoint = 'blah'
if sys.argv[1:]:
   startingpoint = sys.argv[1]

정의되어 있는지 확인하는 것이 아닙니다. 존재하는 경우 정의와 더 비슷합니다. 나는 대체 변수를 분석하는데도 그런 방식을 사용했지만 현재 질문에 대한 대답은 아닙니다.
m3nda

@ erm3nda startingpoint예제에서 변수를 제거 할 수 있지만 질문은 대체 변수를 할당하는 것이므로 방금 동일하게 만들었습니다.
아나톨리 techtonik

1
제거하면 정의되지 않은 변수에 대한 오류가 발생합니다. 나는 질문을 다시 읽었고, 그가 기대하는 것은 변수 대체입니다 :) 그래서 괜찮습니다. 짧은 방법의 조언에 감사드립니다 sys.argv[1:]:. 이것은 위치 인수와 함께 작동하지만 count는 그렇지 않습니다.
m3nda

10

평범한 파이썬 목록입니다. 이를 위해 잡을 수있는 예외는 IndexError이지만 대신 길이를 확인하는 것이 좋습니다.

if len(sys.argv) >= 2:
  startingpoint = sys.argv[1]
else:
  startingpoint = 'blah'

2

지도 내장 fonction으로 작업하는 솔루션!

arg_names = ['command' ,'operation', 'parameter']
args = map(None, arg_names, sys.argv)
args = {k:v for (k,v) in args}

그런 다음 다음과 같이 매개 변수를 호출하면됩니다.

if args['operation'] == "division":
    if not args['parameter']:
        ...
    if args['parameter'] == "euclidian":
        ...

1

argv [1]의 값을 argv에 추가 한 다음 argv [1]이 입력 한 문자열과 같지 않은지 확인할 수 있습니다. 예 :

from sys import argv
argv.append('SomeString')
if argv[1]!="SomeString":
            print(argv[1])

나를 반대 한 사람들은 실수를 명확히하지 않은 것에 대해 부끄럽게 생각합니다.
Hassan Abdul-Kareem

나는 그것이 hackish이기 때문이라고 생각합니다. 누군가 SomeString을 인수로 전달하면 어떨까요? 받아 들일 수 있다면 그것을 사용하는 방법은 1 ~ 5 개의 인수를 말할 수 있습니까?
pbogut 2012-07-24

사용자가 인수를 제공하지 않는 경우 기본값을 설정하는 것은 멋지지만 여전히 끔찍합니다. 추가하고 argv [1]을 사용하십시오.
Felizett

1

작성자가하려는 작업에 매우 가깝습니다. 내가 사용하는 기능은 다음과 같습니다.

def get_arg(index):
    try:
        sys.argv[index]
    except IndexError:
        return ''
    else:
        return sys.argv[index]

따라서 사용법은 다음과 같습니다.

if __name__ == "__main__":
    banner(get_arg(1),get_arg(2))
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.