파이썬에서 명령줄 인수를 처리하는 효과적인 방법
파이썬 스크립트를 실행할 때 명령줄 인수를 사용하는 방법을 배우고 싶으신가요? 파이썬은 sys
, getopt
, argparse
모듈을 통해 이러한 기능을 제공하며, 이를 통해 명령줄 인수를 구문 분석하고 스크립트의 동작을 사용자 정의할 수 있습니다.
파이썬에서 사용자 입력을 받는 일반적인 방법은 input()
함수를 사용하는 것이지만, 특정 경우에는 스크립트 실행 시점에 명령줄을 통해 인수를 전달해야 할 수 있습니다.
이 튜토리얼에서는 파이썬 스크립트를 명령줄에서 실행할 때 옵션과 인수를 어떻게 활용하는지 살펴보고, 파이썬 내장 모듈을 사용하여 이러한 옵션과 인수를 처리하는 방법을 알아보겠습니다.
이제 시작해 보겠습니다!
파이썬에서 sys.argv
의 역할 이해
C 언어 프로그래밍 경험이 있다면 명령줄을 통해 프로그램에 인수를 전달하는 것이 얼마나 편리한지 잘 아실 겁니다. C에서는 main
함수를 다음과 같이 구성하여 이를 처리합니다.
#include<stdio.h> int main(int argc, char **argv){ // argc: 인수의 개수 // argv: 인수 벡터 // 인수 처리 로직 return 0; }
여기서 argc
는 전달된 인수 개수를 나타내고, argv
는 실제 인수를 담고 있는 배열입니다.
파이썬 스크립트를 명령줄 인수로 실행하기
파이썬에서는 python3 filename.py
명령을 사용하여 명령줄에서 스크립트를 실행할 수 있습니다. 이 때, 스크립트에 다양한 명령줄 인수를 추가로 전달할 수도 있습니다.
$ python3 filename.py arg1 arg2 ... argn
sys
모듈은 이러한 명령줄 인수에 접근하고 처리하는 데 필요한 기능을 제공합니다. 특히, sys.argv
는 스크립트 실행 시 전달된 모든 명령줄 인수를 담고 있는 리스트입니다.
아래는 main.py
스크립트를 명령줄 인수를 사용하여 실행하는 예시입니다.
$ python3 main.py hello world python script
for
루프와 enumerate
함수를 함께 사용하여 인수를 쉽게 순회할 수 있습니다.
# main.py import sys for idx, arg in enumerate(sys.argv): print(f"arg{idx}: {arg}")
# 실행 결과 arg0: main.py arg1: hello arg2: world arg3: python arg4: script
결과를 보면 첫 번째 인수(인덱스 0)는 항상 실행되는 파이썬 파일의 이름이고, 이후의 인수는 인덱스 1부터 시작하는 것을 알 수 있습니다.
이것은 명령줄 인수를 받아 처리하는 기본적인 프로그램입니다. 그러나 몇 가지 개선해야 할 점이 있습니다.
- 사용자가 어떤 인수를 전달해야 하는지 어떻게 알 수 있을까요?
- 각 인수는 어떤 의미를 가질까요?
이러한 정보가 부족하면 사용하기 어려울 수 있습니다. 이 문제를 해결하기 위해 getopt
또는 argparse
모듈을 활용할 수 있습니다. 다음 섹션에서 이 모듈들을 사용하는 방법을 자세히 알아보겠습니다.
getopt
모듈을 이용한 파이썬 명령줄 인수 구문 분석
파이썬의 내장 모듈인 getopt
를 사용하여 명령줄 인수를 구문 분석하는 방법을 살펴보겠습니다.
getopt
모듈에서 getopt
함수를 가져온 후, 구문 분석할 인수를 지정하고 스크립트 실행에 필요한 짧은 옵션과 긴 옵션을 설정할 수 있습니다. sys.argv
에서 인덱스 1부터 시작하는 모든 인수를 구문 분석해야 하므로, 구문 분석할 범위는 sys.argv[1:]
가 됩니다.
예를 들어, 메시지 문자열과 파일 이름을 인수로 받도록 설정해 보겠습니다. 짧은 옵션으로 m
과 f
를 사용하고, 긴 옵션으로 message
와 file
을 사용합니다.
특정 옵션에 인수가 필요한지 어떻게 알 수 있을까요?
- 짧은 옵션의 경우, 옵션 이름 뒤에 콜론(:)을 추가하여 해당 옵션에 인수가 필요하도록 지정할 수 있습니다.
- 긴 옵션의 경우, 옵션 이름 뒤에 등호(=)를 추가하여 해당 옵션에 인수가 필요하도록 지정할 수 있습니다. 이렇게 하면 각 옵션과 해당하는 인수를 캡처할 수 있습니다.
이를 적용하여 main.py
파일에 다음 코드를 추가합니다.
# main.py import sys from getopt import getopt opts, args = getopt(sys.argv[1:],'m:f:',['message=','file=']) print(opts) print(args)
여기서 opts
변수에는 옵션과 인수가 튜플 리스트 형태로 저장되고, 전달된 다른 위치 인수는 args
변수에 리스트 형태로 저장됩니다.
이제 메시지와 파일 이름을 전달하여 스크립트를 실행할 수 있으며, 짧은 옵션이나 긴 옵션을 사용할 수 있습니다.
긴 옵션을 사용하여 main.py
를 실행하면 다음과 같은 결과를 얻을 수 있습니다.
$ python3 main.py --message hello --file somefile.txt
opts
변수에는 옵션과 인수가 튜플 형태로 저장되어 있고, 위치 인수가 없으므로 args
는 빈 리스트입니다.
# 실행 결과 [('--message', 'hello'), ('--file', 'somefile.txt')] []
짧은 옵션을 사용하여 동일한 작업을 수행할 수도 있습니다.
$ python3 main.py -m hello -f somefile.txt
# 실행 결과 [('-m', 'hello'), ('-f', 'somefile.txt')] []
⚠️ 주의: 이 예시에서 -m
짧은 옵션은 파이썬 스크립트를 모듈로서 실행할 때 사용하는 -m
명령줄 플래그와 혼동하지 않도록 주의해야 합니다.
예를 들어, main.py
를 실행할 때 python3 -m unittest main.py
를 사용하면 unittest
모듈을 실행하게 됩니다.
우리가 전달하는 다른 위치 인수는 args
변수에 수집될 것이라고 언급했습니다. 예를 들어,
$ python3 main.py -m hello -f somefile.txt another_argument
args
리스트에는 위치 인수 another_argument
가 포함됩니다.
# 실행 결과 [('-m', 'hello'), ('-f', 'somefile.txt')] ['another_argument']
opts
는 튜플 리스트이므로, 루프를 사용하여 튜플을 언패킹하고 각 옵션에 해당하는 인수를 추출할 수 있습니다.
이 인수를 처리한 후 파일 이름과 메시지를 어떻게 사용할 수 있을까요? 파일 쓰기 모드로 열고, 메시지를 대문자로 변환하여 파일에 쓸 수 있습니다.
# main.py import sys from getopt import getopt opts, args = getopt(sys.argv[1:],'m:f:',['message=','file=']) print(opts) print(args) for option, argument in opts: if option == '-m': message = argument if option == '-f': file = argument with open(file,'w') as f: f.write(message.upper())
짧은 옵션과 명령줄 인수를 사용하여 main.py
를 실행해 보겠습니다.
$ python3 main.py -m hello -f thisfile.txt [('-m', 'hello'), ('-f', 'thisfile.txt')] []
main.py
를 실행하면 현재 작업 디렉토리에 ‘thisfile.txt’ 파일이 생성됩니다. 이 파일에는 ‘hello’ 문자열이 대문자로 변환된 ‘HELLO’가 포함되어 있습니다.
$ ls main.py thisfile.txt
$ cat thisfile.txt HELLO
argparse
모듈을 이용한 명령줄 인수 구문 분석
파이썬 표준 라이브러리에 포함된 또 다른 유용한 모듈인 argparse
는 명령줄 인수를 처리하고 명령줄 인터페이스를 구축하는 데 특화된 기능을 제공합니다.
명령줄 인수를 구문 분석하려면 argparse
모듈에서 ArgumentParser
클래스를 가져와야 합니다. ArgumentParser
객체인 arg_parser
를 인스턴스화합니다.
from argparse import ArgumentParser arg_parser = ArgumentParser()
이제 두 개의 명령줄 인수를 추가해 보겠습니다.
message
: 메시지 문자열file
: 작업할 파일 이름
arg_parser
객체의 add_argument()
메서드를 호출하여 이 두 인수를 추가합니다. add_argument()
메서드 호출 시 인수에 대한 설명을 help
문자열로 설정할 수 있습니다.
arg_parser.add_argument('message', help='메시지 문자열') arg_parser.add_argument('file', help='파일 이름')
지금까지 arg_parser
를 인스턴스화하고 명령줄 인수를 추가했습니다. 프로그램이 명령줄에서 실행될 때, arg_parser
객체의 parse_args()
메서드를 사용하여 인수 값을 가져올 수 있습니다.
여기서 인수 네임스페이스를 args
변수에 저장합니다. 따라서 args.인수_이름
을 사용하여 각 인수의 값을 가져올 수 있습니다.
인수 값을 가져온 후, 대소문자를 바꾼 메시지를 (swapcase()
메서드를 사용하여) 파일에 쓸 수 있습니다.
args = arg_parser.parse_args() message = args.message file = args.file with open(file,'w') as f: f.write(message.swapcase())
위의 내용을 모두 합치면 main.py
파일은 다음과 같습니다.
# main.py from argparse import ArgumentParser arg_parser = ArgumentParser() arg_parser.add_argument('message', help='메시지 문자열') arg_parser.add_argument('file', help='파일 이름') args = arg_parser.parse_args() print(args) message = args.message file = args.file with open(file,'w') as f: f.write(message.swapcase())
명령줄 인수 사용법 이해하기
main.py
를 실행할 때 인수 사용법을 확인하려면 --help
긴 옵션을 사용할 수 있습니다.
$ python3 main.py --help usage: main.py [-h] message file positional arguments: message 메시지 문자열 file 파일 이름 optional arguments: -h, --help 이 도움말 메시지를 표시하고 종료합니다
선택적 인수가 없으며, 메시지와 파일 모두 필수 위치 인수입니다. 짧은 옵션 -h
를 사용할 수도 있습니다.
$ python3 main.py -h usage: main.py [-h] message file positional arguments: message 메시지 문자열 file 파일 이름 optional arguments: -h, --help 이 도움말 메시지를 표시하고 종료합니다
보시다시피 두 인수는 기본적으로 위치 인수입니다. 따라서 이러한 인수 중 하나라도 전달하지 않으면 오류가 발생합니다.
예를 들어, 메시지 문자열에 대한 위치 인수를 전달했지만 파일 인수에 대한 값을 제공하지 않았습니다.
이 경우 파일 인수가 필요하다는 오류가 발생합니다.
$ python3 main.py Hello usage: main.py [-h] message file main.py: error: 다음 인수가 필요합니다: file
두 개의 위치 인수를 사용하여 main.py
를 실행하면 네임스페이스 args
에 인수 값이 저장되는 것을 확인할 수 있습니다.
$ python3 main.py Hello file1.txt
# 실행 결과 Namespace(file='file1.txt', message='Hello')
현재 작업 디렉토리의 내용을 확인하면 스크립트가 file1.txt
파일을 생성한 것을 알 수 있습니다.
$ ls file1.txt main.py
원래 메시지 문자열은 ‘Hello’입니다. 대소문자를 바꾼 후 file1.txt
파일의 메시지 문자열은 ‘hELLO’입니다.
$ cat file1.txt hELLO
명령줄 인수를 선택적으로 만드는 방법
이러한 명령줄 인수를 선택 사항으로 만들려면 인수 이름 앞에 --
를 붙일 수 있습니다.
메시지와 파일 인수를 모두 선택 사항으로 만들기 위해 main.py
를 수정해 보겠습니다.
# main.py from argparse import ArgumentParser arg_parser = ArgumentParser() arg_parser.add_argument('--message', help='메시지 문자열') arg_parser.add_argument('--file', help='파일 이름')
명령줄 인수는 모두 선택 사항이므로 이러한 인수에 대한 기본값을 설정할 수 있습니다.
if args.message and args.file: message = args.message file = args.file else: message="Python3" file="myfile.txt"
이 시점에서 main.py
파일은 다음 코드를 포함합니다.
# main.py from argparse import ArgumentParser arg_parser = ArgumentParser() arg_parser.add_argument('--message', help='메시지 문자열') arg_parser.add_argument('--file', help='파일 이름') args = arg_parser.parse_args() print(args) if args.message and args.file: message = args.message file = args.file else: message="Python3" file="myfile.txt" with open(file,'w') as f: f.write(message.swapcase())
사용법을 확인하면 메시지와 파일이 모두 선택적 인수가 된 것을 알 수 있습니다. 이제 이 두 인수 없이 main.py
를 실행할 수 있다는 의미입니다.
$ python3 main.py --help usage: main.py [-h] [--message MESSAGE] [--file FILE] optional arguments: -h, --help 이 도움말 메시지를 표시하고 종료합니다 --message MESSAGE 메시지 문자열 --file FILE 파일 이름
$ python3 main.py
인수 네임스페이스에서 파일과 메시지는 모두 None입니다.
# 실행 결과 Namespace(file=None, message=None)
기본 파일 이름과 메시지인 myfile.txt
와 Python3
이 사용됩니다. 이제 myfile.txt
파일이 작업 디렉토리에 있습니다.
$ ls file1.txt main.py myfile.txt
그리고 대소문자가 바뀐 문자열 pYTHON3
을 포함합니다.
$ cat myfile.txt pYTHON3
--message
및 --file
인수를 모두 사용하여 명령을 더 명확하게 만들 수도 있습니다.
$ python3 main.py --message Coding --file file2.txt
# 실행 결과 Namespace(file='file2.txt', message='Coding')
작업 디렉토리에 file2.txt
가 표시됩니다.
$ ls file1.txt file2.txt main.py myfile.txt
그리고 예상대로 문자열 ‘cODING’을 포함합니다.
$ cat file2.txt cODING
결론
이 튜토리얼에서 배운 내용을 요약하면 다음과 같습니다.
- C 프로그래밍 언어와 마찬가지로 파이썬에서는
sys.argv
인수 벡터를 사용하여 명령줄 인수에 접근할 수 있습니다.sys.argv[0]
은 파이썬 스크립트의 이름이므로, 인수 구문 분석에 사용할 부분은sys.argv[1:]
입니다. - 가독성을 높이고 옵션을 추가하려면
getopt
및argparse
모듈을 사용할 수 있습니다. getopt
모듈을 사용하면 인덱스 1부터 시작하여 명령줄 인수 목록을 구문 분석할 수 있으며, 짧은 옵션과 긴 옵션을 모두 지정할 수 있습니다.- 옵션이 인수를 사용하는 경우 짧은 옵션과 긴 옵션 뒤에 각각 콜론(:)과 등호(=)를 추가하여 지정할 수 있습니다.
- 파이썬의
argparse
모듈을 사용하면ArgumentParser
객체를 인스턴스화하고add_argument()
메서드를 사용하여 필요한 위치 인수를 추가할 수 있습니다. 옵션으로 만들려면 인수 이름 앞에--
를 사용합니다. - 명령줄 인수 값을 가져오려면
ArgumentParser
객체에서parse_args()
메서드를 호출합니다.
다음에는 파이썬에서 보안 해싱을 수행하는 방법을 알아보겠습니다.