imhamburger 님의 블로그

파이썬(Python) - argparse 이용하여 띄어쓰기 포함한 인자값 받기 본문

파이썬(Python)

파이썬(Python) - argparse 이용하여 띄어쓰기 포함한 인자값 받기

imhamburger 2024. 7. 26. 18:42

내가 만들고자 했던 것은,

dt cmd cnt
날짜 명령어 개수

3개의 컬럼으로 이루어진 데이터 테이블을 판다스로 parquet 파일을 만들어 저장하고 터미널에서 cmd 를 입력하면 cmd에 해당하는 cnt 즉 개수가 출력되는 기능을 만들고자 했다.

 

여기서 cmd를 인자로 받아 cnt가 출력되게 만들어야 한다. 따라서 sys를 이용해 다음과 같은 파이썬 코드를 작성하였다.

import pandas as pd
import sys

a = sys.argv[1]

def cnt():

    df = pd.read_parquet("~/tmp/history.parquet")
    fdf = df[df['cmd'].str.contains(a)]
    cnt = fdf['cnt'].sum()
    print(cnt)

인자값을 0이 아닌 1을 준 이유는 0 자리에는 명령실행어가 와야하기 때문이다.

 

사용예시

{명령실행어} {cmd입력}

#출력
...

 

그러나.

이 코드에서 문제는 cmd에 만약 띄어쓰기가 있다면, 에러가 날 것이다. 내가 입력하고 싶은 cmd가 "abc def" 라면 위 코드로 실행했을 때 명령어는 abc와 def 를 따로따로 보고 계산할 것이다. 그렇게되면 나는 인자값을 '1'만 주었으니 에러가 난다.

 

따라서, 이를 해결하기 위해 argparse 를 이용하였다.

argparse 사용방법은 공식문서에 자세히 나와있지만 내가 보기 편하고자 정리를 해보았다.

 

argparse는 무엇인가?

argparse는 파이썬 내장 라이브러리로 명령줄 인자를 쉽게 처리해주는 모듈이다. 정해진 사용방법이 있는데 3개로 구분할 수 있다.

 

 

1. ArgumentParser 객체 생성

ArgumentParser 객체는 명령행을 파이썬 데이터형으로 파싱하는데 필요한 모든 정보를 담고 있다. 여기서 파싱이란 "문장을 분석하고 문법적 관계를 해석하는 행위"이다.

import argparse

parser = argparse.ArgumentParser(
                    prog='{만든 기능명}',
                    description='{기능에 대한 설명}',
                    epilog='{부가설명 등}')

prog, description, epilog는 옵션이다. 적어도되고 안적어도 된다. 아니면 하나만 적어도 된다. 보통 description을 많이 적는 것 같다.

 

 

2. 인자값 추가하기

ArgumentParser 에 인자에 대한 정보를 채우려면 add_argument() 메서드를 호출하면 된다. 이 호출은 ArgumentParser 에게 명령행의 문자열을 객체로 변환하는 방법을 알려준다. 그리고 이 정보를 ArgumentParser가 저장한다.

 

2-1. 위치 인자

위치 인자는 명령어에서 특정 위치에 따라 값을 전달하는 방식이다.

parser.add_argument('filename', type=str, help='무엇이든 적으세요.')

type은 명시를 해줘도 되고 안해줘도 되지만 명시를 안해줄 경우 기본값으로 str 타입으로 설정된다. 그리고 help는 옵션이다.

 

 

2-2. 선택 인자

선택 인자는 앞에 -- 또는 -를 붙여서 전달하는 방식이다.

parser.add_argument('--abc', help='아무거나 적으세요.')

위 코드에 abc 자리에 내가 이름?을 지정하면 된다. --input, -p, --count 등. 마찬가지로 help는 옵션이다.

 

참고로 선택 인자를 필수로 만들어야 한다면, required값에 True를 주면 된다.

parser.add_argument('--abc', required=True, help='아무거나 적으세요.')

 

만약 뒤에 어떤값을 입력안하고 -abc 혹은 --abc 만으로도 설정한 무언가가 출력되게 만들고 싶다면, action = store_true 값을 주면 된다.

parser.add_argument('-abc','--abc', action='store_true')

 

인자에 기본값을 설정하고 싶을 땐, default를 추가하여 기본값으로 설정하고 싶은 것을 적으면 된다.

parser.add_argument('--number', type=int, default=2)

 

 

3. 인자 파싱하기

ArgumentParser가 저장한 정보들을 분석하고 해석해주는 명령행을 작성하면 argparse 사용방법은 끝이다.

args = parser.parse_args()

 

3가지만 기억하자.

  • ArgumentParser : 인자정보를 저장
  • parser.add.argument : 인자정보들 입력
  • args : 저장된 인자정보를 해석

다시 돌아와서... 처음에 나는 sys를 이용해 인자를 받았었다. 그치만 띄어쓰기 문제를 해결하고 싶어서 argparse를 썼다.

 

argparse를 이용한 코드

import pandas as pd
import argparse

parser = argparse.ArgumentParser(description='내가 실행한 명령어 카운트 기능')
parser.add_argument('--input', required=True, help='카운트할 명령어를 입력하세요')


def cnt():
    args = parser.parse_args()
    input_command = args.input

    df = pd.read_parquet("~/tmp/history.parquet")
    fdf = df[df['cmd'].str.contains(input_command)]
    cnt = fdf['cnt'].sum()


    print(cnt)

 

위에서 설명한대로 3가지는 다 써주었고,

한가지 추가된 것은 input_command 라는 변수에 args.input를 지정한 것. 이게 인자값이다.

왜 "input"이라고 명시했냐면,  위에 parser.add_argument 에 --input 이라고 내가 선택인자로 넣어줬기 때문이다.

만약 --input이 아니고 --abc였으면 args.abc 가 된다.

 

 fdf = df[df['cmd'].str.contains(input_command)] 

원래 sys.argv[1]이었지만,  input_command로 넣어야 argparse 인자값을 받을 수 있다.

(사실 변수를 따로 지정안하고 그냥 args.input으로 넣어도 됐을 것 같다.)

 

위 코드를 실행하고싶다면, 다음과 같이 입력해야 한다.

{실행명령어} --input {무언가 입력}

 

사실 공식문서에는 내가 정리한 것보다 더 자세하고 다양한 기능들이 더 많이 있다.

내가 필요한 기능에 맞게 적절히 쓰면 된다.