Summary
argparse๋ Python ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก ํฐ๋ฏธ๋ ๋ช ๋ น์ด๋ฅผ ํตํด ์คํฌ๋ฆฝํธ ๋ด๋ถ์ ๋ณ์ ๊ฐ์ ์ง์ ์์ ํ์ง ์๊ณ ๋ ์ ์ฐํ๊ฒ ์ ์ดํ ์ ์๊ฒ ํด์ฃผ๋ CLI ๋๊ตฌ์ด๋ค.- ํ์ ์์ฑ โ ์ธ์ ์ถ๊ฐ โ ๋ถ์ ์ด๋ผ๋ 3๋จ๊ณ์ ๋ช ํํ ํ๋ฆ์ ํตํด ์ง๊ด์ ์ผ๋ก ํ๋ก๊ทธ๋จ์ ๊ตฌ์ฑํ๋ค.
- ํ์ ์ ๋ ฅ๊ฐ์ธ โ์์น ์ธ์โ์ ๋ถ๊ฐ์ ์ธ ์ค์ ์ฉ์ธ โ์ ํ ์ธ์โ๋ก ๊ตฌ๋ถํ์ฌ ๋ค์ํ ์คํ ํ๊ฒฝ์ ์ค๊ณํ ์ ์๋ค.
add_argument๋ฉ์๋ ๋ด ๋ค์ํ ์ต์ ๋ค(type,default,choices,action๋ฑ)์ ํ์ฉํด ๋ฐ์ดํฐ ํ๋ณํ, ๊ธฐ๋ณธ๊ฐ ์ค์ , ์ ํจ์ฑ ๊ฒ์ฌ ์๋ํ, ํ๋๊ทธ ์ค์ ๋ฑ์ ์์ฝ๊ฒ ๊ตฌํํ ์ ์๋ค.
0. ๋ค์ด๊ฐ๋ฉฐ
๋งค๋ฒ Python ์คํฌ๋ฆฝํธ ๋ด์์ ๋ณ์๋ฅผ ์ง์ ์์ ํ๋ ๊ฒ์ ๊ท์ฐฎ์ ์์ ์ด๋ค.
Python ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ธ argparse ๋ฅผ ์ฌ์ฉํ์ฌ, ํฐ๋ฏธ๋์ ํตํด Python ํ์ผ ์คํํ ๋ ํฐ๋ฏธ๋์์ ์ต์
์ ์
๋ ฅํด์ Python ์ฝ๋ ๋ด ๋ณ์ ๊ฐ๋ค์ ์ ์ดํด๋ณด์.
์ฌ๊ธฐ์๋ argparse๋ฅผ ์ด์ฉํ์ฌ ์ฝ๊ฒ ์ฌ์ฉํ ์ ์๋ CLI(Command Line Interface) ๋๊ตฌ๋ฅผ ๋ง๋๋ ๋ฐฉ๋ฒ์ ์ ๋ฆฌํ์๋ค.
1. ๊ฐ์
argparse ๋?
argparse๋ ํ๋ก๊ทธ๋จ ์คํ ์ ์ปค๋งจ๋ ๋ผ์ธ์์ ์ธ์(Argument)๋ฅผ ๋ฐ์, ์ด๋ฅผ ํ์ด์ฌ ๋ด๋ถ ๋ณ์๋ก ์ฝ๊ฒ ๋ณํํด ์ฃผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
์๋ฅผ ๋ค์ด, ๋จ์ํ python main.py๋ก ์คํํ๋ ๊ฒ์ด ์๋๋ผ, ์๋์ฒ๋ผ ์คํํ๊ณ ์ถ์ ๋ ์ฌ์ฉํ๋ค.
์๋ ๋ช
๋ น์ด์์ extract, 10, verbose ๊ฐ์ ๊ฐ๋ค์ ํ์ด์ฌ์ด ์์๋จน๋๋ก ๋์์ฃผ๋ ๊ฒ์ด ๋ฐ๋ก argparse์ด๋ค.
python main.py extract --sample 10 --verbose2. ๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ
2.1 ํ๋ฆ
argparse์ ์ฌ์ฉ ํ๋ฆ์ ์ ํํ๋์ด ์์ผ๋ฉฐ, 3๋จ๊ณ๋ง ๊ธฐ์ตํ๋ฉด ๋๋ค.
- Parser ์์ฑ(
ArgumentParser): ๋ด์ ๊ทธ๋ฆ(๊ฐ์ฒด)์ ์์ฑ - ์ธ์ ์ถ๊ฐ (
add_argument): ์ด๋ค ์ ๋ ฅ์ ๋ฐ์์ง ๊ท์น์ ์ ํ๊ธฐ - ๋ถ์ (
parse_args): ๋ค์ด์จ ์ ๋ ฅ์ ์ค์ ๋ก ํด์ํ์ฌ ๋ณ์์ ๋ด์ต๋๋ค.
import argparse
# 1. Parser ์์ฑ
parser = argparse.ArgumentParser(description="์ด ํ๋ก๊ทธ๋จ์ ์์ ์
๋๋ค.")
# 2. ์ธ์ ์ถ๊ฐ
parser.add_argument("name", help="์ฌ์ฉ์ ์ด๋ฆ")
parser.add_argument("--age", help="๋์ด")
# 3. ๋ถ์
args = parser.parse_args()
print(f"์ด๋ฆ: {args.name}, ๋์ด: {args.age}")2.2 ์์น ์ธ์ vs ์ ํ ์ธ์
add_argument๋ฅผ ์ฌ์ฉํ ๋ ๊ฐ์ฅ ํท๊ฐ๋ฆฌ๋ ๋ถ๋ถ์ผ๋ก ์ธ์ ์ด๋ฆ ์์ ๋ถ๋ ํ์ดํ(-)์ ์ ๋ฌด๊ฐ ๊ฒฐ์ ์ ์ธ ์ฐจ์ด
| ๊ตฌ๋ถ | ์์น ์ธ์(Positional Arguments) | ์ ํ ์ธ์(Optional Arguments) |
|---|---|---|
| ํน์ง | ์ด๋ฆ ์์ ํ์ดํ (-) ์๋ค (์: filename, mode) | ์ด๋ฆ ์์ ํ์ดํ(-, --) ์ด ๋ถ๋๋ค (์: -f, --file) |
| ๊ท์น | ํ์ ์ ๋ ฅ์ด๋ฉฐ, ์์ฑ ์์๊ฐ ์ค์ | ์ ๋ ฅํ์ง ์์๋ ์๋ฌ ๋ฐ์ํ์ง ์๊ณ , ์์๋ ์๊ด์๋ค |
| ์ฉ๋ | ํ๋ก๊ทธ๋จ ์คํ ์, ์์ด์๋ ์ ๋ ํต์ฌ ๋ฐ์ดํฐ | ์ต์ ์ค์ , ๋ชจ๋ ๋ณ๊ฒฝ ๋ฑ ๋ถ๊ฐ์ ์ธ ๊ธฐ๋ฅ |
2.3 ํต์ฌ ์ต์ ๋ค
add_argument()๋ฉ์๋ ๋ด ๊ธฐ๋ฅ ์ค๋ช
| ์ต์ | ๊ธฐ๋ฅ | ์ค๋ช |
|---|---|---|
type | ํ์ ์ง์ | ์ ๋ ฅ๊ฐ์ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ฌธ์์ด(str) ๋ก ๋ค๋ฅธ ํ์ ์ผ๋ก ๋ณํํ๋ ๊ฒฝ์ฐ ์ฌ์ฉ |
defalut | ๊ธฐ๋ณธ๊ฐ ์ค์ | ์ต์ ๋ฏธ์ ๋ ฅ์ ๊ธฐ๋ณธ์ผ๋ก ์ฌ์ฉํ ๊ฐ ์ง์ |
choices | ์ ํ์ง ์ ํ | ์ ํด์ง ๊ฐ ์ธ ์ ๋ ฅ์ด ๋ค์ด์ค๋ฉด ์๋ฌ ์ผ์ผํด (์ ํจ์ฑ ๊ฒ์ฌ ์๋ํ) |
action | ํ๋๊ทธ ์ค์ | ๊ฐ์ด ์๋ ์ต์ ์กด์ฌ ์ฌ๋ถ ๊ฒ์ฌ |
required | ํ์ ์ต์ ์ค์ | ์ ํ ์ธ์์ง๋ง, ๋ฐ๋์ ์ ๋ ฅ์ ๊ฐ์ |
nargs | ๋ฆฌ์คํธ๋ก ๋ฐ๊ธฐ | ์ ๋ ฅ๊ฐ์ ๋ฆฌ์คํธ๋ก ๋ฐ๊ธฐ |
# 1. ํ์
์ง์ : count ๋ณ์๋ฅผ intํ์ผ๋ก ์ง์
parser.add_argument("--count", type = int)
# 2. ๊ธฐ๋ณธ๊ฐ ์ค์ : mode ๋ณ์ ๊ธฐ๋ณธ๊ฐ์ 'normal'๋ก ์ค์
parser.add_argument("--mode", defalut = "normal")
# 3. ์ ํ์ง ์ ํ: color ๋ณ์๋ red, blue, green ๊ฐ๋ง ๋ฐ์
parser.add_argument("color", choices = ['red', 'blue','green'])
# 4. ํ๋๊ทธ ์ค์ : --verbose๋ฅผ ์
๋ ฅํ๋ฉด True, ๊ทธ๋ ์ง ์์ผ๋ฉด False
parser.add_argument('--verbose', action = 'store_true')
# 5. ํ์ ์ต์
: api-key ๋ณ์๋ ํ์ ์
๋ ฅ๊ฐ์ผ๋ก ์ค์
parser.add_argument('--api-key', required = True)
# 6. ๋ฆฌ์คํธ ๋ฐ๊ธฐ: files ๋ณ์๋ list ๊ฐ์ ๋ฐ๊ธฐ (์์, ['a.txt', 'b.txt', 'c.txt'])
parser.add_argument('--files', nargs = '*')3. ํ์ฉ
์ฝ๋
์๋ ์ฝ๋๋ mode๋ผ๋ ์์น ์ธ์(ํ์ ์
๋ ฅ)์ --sample์ด๋ผ๋ ์ ํ ์ธ์(์ ํ ์
๋ ฅ) ์ต์
์ ์กฐํฉํ์ฌ ์ฌ์ฉํ๋ค.
import argparse
import sys
def main():
# 1. ํ์ ์์ฑ (description์ผ๋ก ๋์๋ง ์ ๊ณต)
parser = argparse.ArgumentParser(description="์ํํธ ๋๋ฉด ๋ฐ์ดํฐ ์ฒ๋ฆฌ ํ์ดํ๋ผ์ธ")
# [์์น ์ธ์] ์คํ ๋ชจ๋ (choices๋ก ์คํ ๋ฐฉ์ง)
parser.add_argument(
"mode",
choices=["extract", "convert", "validate", "all"],
help="์คํ ๋ชจ๋ (extract: ์ถ์ถ, convert: ๋ณํ, validate: ๊ฒ์ฆ, all: ์ ์ฒด)"
)
# [์ ํ ์ธ์] ํ
์คํธ์ฉ ์ํ ๊ฐ์ (int ํ๋ณํ)
# ํ: ๋จ์ถ ์ต์
'-s'์ ์ ์ฒด ์ต์
'--sample'์ ๊ฐ์ด ์ง์ ํ๋ฉด ํธ๋ฆฌํจ
parser.add_argument(
"-s", "--sample",
type=int,
default=None,
help="ํ
์คํธ๋ฅผ ์ํด ์ฒ๋ฆฌํ ์ํ ์ด๋ฏธ์ง ๊ฐ์ (๊ธฐ๋ณธ๊ฐ: ์ ์ฒด)"
)
# [์ ํ ์ธ์] ์์ธ ๋ก๊ทธ ์ถ๋ ฅ (ํ๋๊ทธ)
parser.add_argument(
"-v", "--verbose",
action="store_true",
help="์์ธ ๋ก๊ทธ ์ถ๋ ฅ ํ์ฑํ"
)
# ์ธ์ ๋ถ์
args = parser.parse_args()
# --- ์ค์ ๋ก์ง ---
print(f"๐ ์คํ ๋ชจ๋: {args.mode}")
if args.verbose:
print("๐ข ์์ธ ๋ก๊ทธ ๋ชจ๋๊ฐ ์ผ์ก์ต๋๋ค.")
if args.sample:
print(f"๐งช [TEST] ์ํ {args.sample}๊ฐ๋ง ์ฒ๋ฆฌํฉ๋๋ค.")
else:
print("โ
์ ์ฒด ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํฉ๋๋ค.")
# ๋ชจ๋๋ณ ๋ถ๊ธฐ ์ฒ๋ฆฌ
if args.mode in ["extract", "all"]:
print("... ๋ฐ์ดํฐ ์ถ์ถ ์ค ...")
# run_extraction(limit=args.sample) ํธ์ถ
if args.mode in ["convert", "all"]:
print("... ๋ฐ์ดํฐ ๋ณํ ์ค ...")
if __name__ == "__main__":
main()์คํ ๊ฒฐ๊ณผ ์์
๊ฐ ์ํฉ๋ณ ๊ฒฐ๊ณผ ์์
# 1. ๋์๋ง ํ์ธ
>>> python main.py -h
### help ๋ฉ์์ง์ usage๊ฐ ์ถ๋ ฅ
# 2. ์ ์ ์คํ: ๋ชจ๋(extract), ์ํ ๊ฐ์(5), ์์ธ ๋ก๊ทธ ์ถ๋ ฅ
>>> python main.py extract -s 5 --verbose
# [output]
๐ ์คํ ๋ชจ๋: extract
๐ข ์์ธ ๋ก๊ทธ ๋ชจ๋๊ฐ ์ผ์ก์ต๋๋ค.
๐งช [TEST] ์ํ 5๊ฐ๋ง ์ฒ๋ฆฌํฉ๋๋ค.
... ๋ฐ์ดํฐ ์ถ์ถ ์ค ...
# 3. ์๋ฌ: ์์น ์ธ์๊ฐ ์ค ์ ํจํ ๊ฐ์ด ์๋ ๊ฒฝ์ฐ
>>> python main.py delete
# [output]
usage: main.py [-h] [-s SAMPLE] [-v] {extract,convert,validate,all}
main.py: error: argument mode: invalid choice: 'delete' ...๋ง์น๋ฉฐ
argparse๋ฅผ ์ฌ์ฉํ๋ฉด ์ฝ๋ ์์ ์์ด ํฐ๋ฏธ๋ ๋ช
๋ น์ด๋ง์ผ๋ก ํ๋ก๊ทธ๋จ์ ๋์์ ์ ์ฐํ๊ฒ ๋ฐ๊ฟ ์ ์๋ค. choices๋ฅผ ํ์ฉํ ์ ํจ์ฑ ๊ฒ์ฌ์ --help ์๋ ์์ฑ ๊ธฐ๋ฅ์ ๊ฐ๋ฐ์์ ์๊ณ ๋ฅผ ๋์ด์ค๋ค.
Reference