Parse Argument จาก Command Line บน Python อย่างง่ายดายด้วย Argparse

เวลาเราเขียนโปรแกรมส่วนใหญ่ โปรแกรมของเราจะต้องมีความสามารถในการตั้งค่าอะไรบางอย่างได้ เช่น Port สำหรับการเชื่อมต่อ หรืออาจจะเป็นค่า Parameter ต่าง ๆ ที่จำเป็น ทำให้เราจะต้องมีวิธีการบางอย่างเช่น การใช้ Environment Variable หรือจะเป็นการเก็บลงเป็น Config File แต่วันนี้เราจะพามาดูอันที่ง่ายที่สุดกันอย่างการใช้ Argument ที่เราได้รับจากคำสั่งตอนเราสั่ง Run Program ด้วย Argparse

ถ้าไม่มี Argparse เราทำยังไง?

จริง ๆ แล้ว ถ้าเราไม่ใช้ Argparse ถามว่าเราสามารถดึงค่าจาก Argument ที่เราใส่เข้ามาได้มั้ย คำตอบคือได้ ผ่าน sys Module ได้ตรง ๆ เลย เรามาลองกัน

import sys

print(sys.argv)

และให้เราเซฟเป็น File เก็บไว้ เช่นอาจจะชื่อว่า arg_tester.py ก็ได้ แล้วตอนสั่งรัน เราอาจจะรันด้วยคำสั่ง python arg_tester.py --option1 hello --option2 word ดู ลองดูว่ามันจะออกมาเป็นอะไร

['arg_tester.py', '--option1', 'hello', '--option2', 'world']

สิ่งที่เราได้ออกมา ก็จะเป็นแบบนี้เลย เราจะเห็นเลยว่า มัน Parse จาก Whitespace ล้วน ๆ เลย การที่เราจะแยกออกมาเป็น Option ดูแล้วเราน่าจะต้องเป็นคนทำเองสินะ ซึ่งวิธีทำมันก็ไม่น่ายากใช่ม่ะ เราก็แค่ดูเลข Index แล้วลอกลงมาเลยยังได้ แต่นั่นก็ทำให้เกิดปัญหาอีกว่า ถ้า User กวนเท้าละ ใส่ Option 2 ขึ้นก่อน ถ้าเราใช้เลข Index ก็แตกเลยถูกม่ะ ไม่ได้ ดังนั้น การเช็คก็อาจจะต้องไล่ไป แล้วถ้าเจอ ขีด 2 อันแปลว่าเป็นชื่อ Option ละ ตัวต่อไปต้องเป็นค่าของมันแน่ ๆ ก็ลอกลงมาใส่ Dictionary ก็น่าจะจบ

แต่ปัญหามันก็ยังไม่จบอีก เพราะ ถ้าเกิดลืมใส่ค่าละใส่มาแต่ชื่อ Option ทำให้ตัวต่อไปมันจะกลายเป็น ชื่อ Option แทน ก็ต้องเช็คอีกว่าตัวต่อไปมันเป็นชื่อ Option รึเปล่า สั้น ๆ ก็คือ เราว่ามันเขียนไม่ยากหรอก แต่มันน่ารำคาญมากกว่าถ้าเราจะต้องมานั่งเขียนทุกครั้ง เพราะมันเป็นส่วนที่เราใช้กันเยอะมาก ๆ ไหนจะเมื่อ User ใส่ -h เพื่อดู Command และรายละเอียดอีก ก็คือแค่ส่วนที่ใช้คุยกับ User ก็น่าปวดหัวแล้วทั้ง ๆ ที่มันควรจะเป็นเรื่องที่ไม่ยากเพราะเราใช้ทุกครั้ง ทำให้ Argparse เข้ามามีประโยชน์ทันที

ลองมาใช้ Argparse กัน

Argparse เป็น Built-in Module จาก Python อยู่แล้วเราไม่จำเป็นที่ต้องมาลงเองเลย เราสามารถ Import เข้ามาใช้งานได้ทันที เรามาลองใช้งานคร่าว ๆ กัน

import argparse
parser = argparse.ArgumentParser()

ขั้นตอนแรก เราจะต้องสร้าง Object ของ Parser กันก่อน โดยผ่านคำสั่งด้านบนได้เลย ก็จะพร้อมใช้

parser.add_argument("--option1", help="Option 1",type=str) 
parser.add_argument("--option2", help="Option 2",type=str) 

ต่อไป เราจะต้องมาบอกมันว่า Option ที่เราจะมีให้ User มันทำอะไรได้บ้าง จากตัวอย่างด้านบน เราบอกว่า มันจะมี option1 และ option2 เหมือนในตัวอย่างแรกเลย แล้วมันจะมี Argument ที่ชื่อว่า Help เดี๋ยวเรามาลองดูกันว่ามันคืออะไร และสุดท้าย เราจะต้องกำหนดด้วยว่า ค่าที่เรารับเข้ามามันเป็นประเภทไหน โดยที่ Argparse มันจะเช็ค และแปลงให้เราพร้อมใช้เลย ไม่ต้องมานั่งทำเองอีกแล้ว

args = parser.parse_args()

หลังจากเราประกาศ Arugment หรือ Option ที่เราต้องการเรียบร้อยแล้ว เราก็จะให้มันทำการ Parse Argument เข้ามาได้เลย เน้นย้ำว่าบรรทัดด้านบนจะต้องทำงานหลังจากเราประกาศ Argument แล้วนะไม่งั้นมันจะไม่ขึ้นเด้อออ

usage: tester.py [-h] [--option1 OPTION1] [--option2 OPTION2]

optional arguments:
  -h, --help         show this help message and exit
  --option1 OPTION1  Option 1
  --option2 OPTION2  Option 2

Help ที่เราค้างไว้เมื่อครู่มันมาอยู่ตรงนี้เอง เมื่อเราพิมพ์ -h เป็น Option มันจะขึ้นแบบด้านบนมาให้เราเลย โดยที่เราไม่ได้ไปเขียนนิน่า นั่นเป็นเพราะ Argparse มัน Generate ให้เราเองเลย จาก addargument() ที่เราบอกมันไปเมื่อครู่ จากเรื่องที่เราต้องมานั่ง Update เอง ตอนนี้ Python มันทำให้เราหมดเลย แค่บอกมันว่ามีอะไรบ้างเท่านั้นก็พอแล้ว

print(args.option1, args.option2)

ในการเข้าถึงค่าที่ Argparse จัดการให้เราแล้ว เราสามารถเข้าถึงผ่านตัวแปร args ที่เราประกาศไว้ตอนที่สั่งให้มัน Parse Arugment ได้เลย โดยผ่านการใช้จุดได้เลย ดั่งตัวอย่างด้านบน เราไม่ต้องมานั่งเช็คเลยว่า เห้ย option 1 กับ 2 มันมีมั้ย เพราะมันถูกจัดการมาล่วงหน้าโดย Argparse แล้วสะดวกมาก ๆ

สรุป

Argparse เข้ามาช่วยล่นงานเราให้ง่ายขึ้นมาก ๆ ผ่านการจัดการ Argument ให้เรา ทั้งเรื่องของการ Parse ที่เคยเป็นเรื่องยากต้องคิดเคสมาดักสารพัด และเรื่องของ Manual ที่เป็นเรื่องที่ Developer หลายคนแหยงมาก ๆ ขี้เกียจเขียนแหละดูออกว่าซั่น ลดปัญหาเรื่องของ Code ประหลาด ๆ ที่ทำให้สกปรกไปทั่วจากส่วนที่ใช้ติดต่อกับผู้ใช้ไปได้เยอะมาก ๆ แนะนำเลยว่าให้ลองใช้ดูแล้วจะติดใจ