Python에서 명령줄 인수를 구문 분석하는 방법

명령줄 인수로 Python 스크립트를 실행하고 싶습니까? Python에서 sys, getopt 및 argparse 모듈을 사용하여 명령줄 인수를 구문 분석하는 방법을 알아봅니다.

Python에서 사용자 입력을 읽으려면 input() 함수를 사용합니다. 그러나 일부 응용 프로그램의 경우 명령줄에서 스크립트를 실행하는 동안 특정 인수를 전달해야 할 수 있습니다.

이 자습서에서는 명령줄에서 옵션 및 인수를 사용하여 Python 스크립트를 실행하는 방법을 배웁니다. 그런 다음 Python의 내장 모듈을 사용하여 이러한 옵션과 인수를 구문 분석하는 방법을 배웁니다.

의 시작하자!

파이썬에서 sys.argv 이해하기

C로 프로그래밍한 경우 프로그램에 인수를 전달하는 가장 간단한 방법 중 하나는 명령줄을 통하는 것임을 알고 있습니다. 이를 위해 다음과 같이 기본 기능을 구성할 수 있습니다.

#include<stdio.h>

int main(int argc, char **argv){
    //argc: argument count
    //argv: argument vector
    
    //do something on the args

    return 0;
}

여기서 argc는 인수 개수를 나타내고 argv는 인수 벡터를 나타냅니다.

명령줄 인수로 Python 스크립트 실행

Python에서는 python3 filename.py를 사용하여 명령줄에서 Python 스크립트를 실행할 수 있습니다. 그렇게 할 때 임의 개수의 명령줄 인수를 전달할 수도 있습니다.

$ python3 filename.py arg1 arg2 ... argn

sys 모듈은 이러한 명령줄 인수에 액세스하고 처리하기 위한 기본 지원을 제공합니다. sys.argv는 Python 스크립트를 실행할 때 전달하는 모든 명령줄 인수 목록입니다.

다음은 명령줄 인수를 사용하여 main.py를 실행하는 예입니다.

$ python3 main.py hello world python script

간단한 for 루프 및 열거 함수를 사용하여 인수 벡터를 반복할 수 있습니다.

# main.py

import sys

for idx, arg in enumerate(sys.argv):
    print(f"arg{idx}: {arg}")
# Output
arg0:main.py
arg1:hello
arg2:world
arg3:python
arg4:script

첫 번째 인수(인덱스 0)가 Python 파일의 이름임을 알 수 있습니다. 그리고 후속 인수는 인덱스 1에서 시작합니다.

이것은 명령줄 인수를 수락하고 처리하는 최소한의 작업 프로그램입니다. 그러나 다음과 같은 몇 가지 문제가 있습니다.

  • 프로그램 사용자는 전달할 인수를 어떻게 알 수 있습니까?
  • 그리고 이러한 주장은 무엇을 의미합니까?

이것은 명확하지 않습니다. 이 문제를 해결하기 위해 getopt 또는 argparse 모듈을 사용할 수 있습니다. 그리고 우리는 다음 섹션에서 그것을 배울 것입니다.✅

Python의 getopt를 사용한 명령줄 인수 구문 분석

내장 getopt 모듈을 사용하여 명령줄 인수를 구문 분석하는 방법을 알아보겠습니다.

getopt 모듈에서 getopt를 가져온 후 구문 분석할 인수와 스크립트를 실행할 짧은 옵션 및 긴 옵션을 지정할 수 있습니다. sys.argv의 인덱스 1에서 시작하는 모든 인수를 구문 분석해야 합니다. 따라서 구문 분석할 슬라이스는 sys.argv입니다.[1:].

여기에는 메시지 문자열과 파일 이름이 필요합니다. 짧은 옵션으로 m과 f를 사용하고 긴 옵션으로 메시지와 파일을 사용합시다.

그러나 특정 옵션에 인수가 필요한지 어떻게 확인합니까?

  • 짧은 옵션에서는 짧은 옵션 이름 뒤에 콜론(:)을 추가하여 옵션에 인수가 필요하도록 만들 수 있습니다.
  • 마찬가지로 긴 옵션에서 긴 옵션 뒤에 = 기호를 추가할 수 있습니다. 이러한 옵션과 각각의 인수를 캡처할 수 있습니다.

이를 추가하면 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는 빈 목록입니다.

# Output
[("--message', 'hello'), ('--file', 'somefile.txt')]
[]

마찬가지로 다음과 같이 짧은 옵션을 사용할 수도 있습니다.

$ python3 main.py -m hello -f somefile.txt
# Output
[('-m', 'hello'), ('-f', 'somefile.txt')]
[]

⚠️ 이 예제의 -m short 옵션은 Python 스크립트를 실행할 때 모듈을 기본 모듈로 실행하는 데 사용되는 명령줄 플래그 -m과 혼동하지 마십시오.

예를 들어, main.py를 실행할 때 python3 -m unittest main.py를 사용하여 unittest를 기본 모듈로 실행합니다.

우리가 전달하는 다른 모든 위치 인수는 args 변수에 수집될 것이라고 언급했습니다. 예를 들면 다음과 같습니다.

$ python3 main.py -m hello -f somefile.txt another_argument

args 목록에는 위치 인수 another_argument가 포함되어 있습니다.

# Output
[('-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를 실행해 보겠습니다.

$ python 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로 명령줄 인수를 구문 분석하는 방법

역시 Python 표준 라이브러리에 내장된 argparse 모듈은 명령줄 인수를 구문 분석하고 명령줄 인터페이스를 빌드하는 기능을 제공합니다.

명령줄 인수를 구문 분석하려면 argparse 모듈에서 ArgumentParser 클래스를 가져오겠습니다. 여기서는 ArgumentParser 개체인 arg_parser를 인스턴스화했습니다.

from argparse import ArgumentParser

arg_parser = ArgumentParser()

다음으로 두 개의 명령줄 인수를 추가하고 싶습니다.

  • 메시지: 메시지 문자열 및
  • file: 작업할 파일의 이름.

이제 arg_parser에서 add_argument() 메서드를 호출하여 이 두 인수를 모두 추가합니다. add_argument() 메서드 호출에서 도움말을 문자열(인수 설명)로 설정할 수 있습니다.

arg_parser.add_argument('message',help='message string')
arg_parser.add_argument('file',help='filename')

지금까지 arg_parser를 인스턴스화하고 명령줄 인수를 추가했습니다. 프로그램이 명령줄에서 실행될 때 arg_parser에서 parse_args() 메서드를 사용하여 인수 값을 가져올 수 있습니다.

여기에서 변수 args에서 인수 네임스페이스를 캡처합니다. 따라서 args.argument_name을 사용하여 인수 값을 가져올 수 있습니다.

인수 값을 가져온 후 대소문자가 바뀐 메시지 문자열(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='message string')
arg_parser.add_argument('file',help='filename')

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 long 옵션을 사용할 수 있습니다.

$ python3 main.py --help
usage: main.py [-h] message file

positional arguments:
  message     message string
  file        filename

optional arguments:
  -h, --help  show this help message and exit

선택적 인수가 없으며 메시지와 파일 모두 필수 위치 인수입니다. 또는 짧은 옵션 -h를 사용할 수도 있습니다.

$ python3 main.py -h
usage: main.py [-h] message file

positional arguments:
  message     message string
  file        filename

optional arguments:
  -h, --help  show this help message and exit

보시다시피 두 인수는 기본적으로 위치 인수입니다. 따라서 이러한 인수 중 하나 이상을 전달하지 않으면 오류가 발생합니다.

여기에서 메시지 문자열에 대한 위치 인수(Hello)를 전달했지만 파일 인수에 대한 값을 제공하지 않았습니다.

그리고 파일 인수가 필요하다는 오류가 발생합니다.

$ python3 main.py Hello
usage: main.py [-h] message file
main.py: error: the following arguments are required: file

두 위치 인수를 사용하여 main.py를 실행하면 네임스페이스 args에 인수 값이 포함되어 있음을 알 수 있습니다.

$ python3 main.py Hello file1.txt
# Output
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='message string')
arg_parser.add_argument('--file',help='filename')

명령줄 인수는 모두 선택 사항이므로 이러한 인수에 대한 기본값을 설정할 수 있습니다.

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='message string')
arg_parser.add_argument('--file',help='filename')

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         show this help message and exit
  --message MESSAGE  message string
  --file FILE        filename
$ python3 main.py

인수 네임스페이스에서 파일과 메시지는 모두 None입니다.

# Output
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
# Output
Namespace(file="file2.txt", message="Coding")

작업 디렉토리에 ‘file2.txt’가 표시됩니다.

$ ls
file1.txt  file2.txt  main.py  myfile.txt

그리고 예상대로 문자열 ‘cODING’을 포함합니다.

$ cat file2.txt
cODING

결론

이 튜토리얼에서 배운 내용을 요약하면 다음과 같습니다.

  • C 프로그래밍 언어와 마찬가지로 Python에서는 인수 벡터 sys.argv를 반복하여 명령줄 인수에 액세스할 수 있습니다. sys.argv[0] Python 스크립트의 이름입니다. 따라서 인수 sys.argv를 구문 분석하는 데 관심이 있습니다.[1:].
  • 그러나 가독성을 높이고 옵션을 추가하려면 getopt 및 argparse 모듈을 사용할 수 있습니다.
  • getopt 모듈을 사용하여 인덱스 1에서 시작하여 목록 끝까지 명령줄 인수 목록을 구문 분석할 수 있습니다. 짧은 옵션과 긴 옵션을 모두 지정할 수 있습니다.
  • 옵션이 인수를 취하는 경우 짧은 옵션과 긴 옵션 뒤에 각각 콜론(:)과 =를 지정할 수 있습니다.
  • Python의 argparse 모듈을 사용하면 ArgumentParser 객체를 인스턴스화하고 add_argument() 메서드를 사용하여 필요한 위치 인수를 추가할 수 있습니다. 옵션으로 만들려면 인수 이름 앞에 —를 사용하십시오.
  • 명령줄 인수 값을 검색하려면 ArgumentParser 객체에서 parse_args() 메서드를 호출합니다.

다음으로 Python에서 보안 해싱을 수행하는 방법을 알아봅니다.