อาร์กิวเมนต์บรรทัดคำสั่งใน Python

ขององค์กร

เนื่องจาก Python เป็นภาษาโปรแกรมยอดนิยม อีกทั้งยังรองรับระบบปฏิบัติการส่วนใหญ่และไลบรารี่จำนวนมากที่ทำให้การประมวลผลอาร์กิวเมนต์บรรทัดคำสั่งเป็นเรื่องง่าย จึงมีการใช้กันอย่างแพร่หลายในการสร้างเครื่องมือบรรทัดคำสั่งเพื่อวัตถุประสงค์หลายประการ เครื่องมือเหล่านี้มีตั้งแต่แอป CLI ธรรมดาไปจนถึงแอปที่ซับซ้อนกว่า เช่น AWS แย่ เครื่องมือ

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

โดยทั่วไป อาร์กิวเมนต์จะถูกส่งผ่านไปยังเครื่องมือ CLI แตกต่างกันไป ขึ้นอยู่กับระบบปฏิบัติการของคุณ:

  • เหมือน Unix: - ตามด้วยจดหมายเช่น -h,หรือ -- ตามด้วยคำเช่น --help
  • Windows: / ตามด้วยตัวอักษรหรือคำเช่น /help

แนวทางที่แตกต่างกันเหล่านี้เกิดขึ้นเนื่องจากเหตุผลทางประวัติศาสตร์ หลายโปรแกรมบนระบบที่คล้าย Unix รองรับทั้งเครื่องหมายขีดกลางและขีดคู่ สัญกรณ์ขีดกลางเดียวส่วนใหญ่จะใช้กับตัวเลือกตัวอักษรตัวเดียว ในขณะที่ขีดกลางคู่แสดงรายการตัวเลือกที่อ่านง่ายกว่า ซึ่งมีประโยชน์อย่างยิ่งสำหรับตัวเลือกที่ซับซ้อนซึ่งต้องมีความชัดเจนมากขึ้น

หมายเหตุ: ในบทความนี้เราจะเน้นไปที่รูปแบบที่เหมือน Unix เท่านั้น - และ --.

โปรดทราบว่าทั้งชื่อและความหมายของอาร์กิวเมนต์นั้นเฉพาะเจาะจงสำหรับโปรแกรม ไม่มีคำจำกัดความทั่วไป นอกเหนือจากแบบแผนทั่วไปบางประการ เช่น --help สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการใช้เครื่องมือ ในฐานะผู้พัฒนาสคริปต์ Python คุณจะต้องตัดสินใจว่าจะมอบอาร์กิวเมนต์ใดให้กับผู้โทรและสิ่งที่พวกเขาทำ สิ่งนี้ต้องมีการประเมินที่เหมาะสม

เมื่อรายการอาร์กิวเมนต์ที่มีอยู่ของคุณเพิ่มมากขึ้น โค้ดของคุณก็จะซับซ้อนมากขึ้นในการพยายามแยกวิเคราะห์อาร์กิวเมนต์อย่างแม่นยำ โชคดีที่มีไลบรารีจำนวนมากใน Python ที่พร้อมให้ความช่วยเหลือคุณในเรื่องนี้ เราจะกล่าวถึงวิธีแก้ปัญหาที่พบบ่อยที่สุดบางส่วน ซึ่งมีตั้งแต่ "ทำเอง" ด้วย sys.argvสู่แนวทาง "ทำเพื่อคุณ" ด้วย argparse.

การจัดการอาร์กิวเมนต์บรรทัดคำสั่งด้วย Python

Python 3+ และระบบนิเวศรอบๆ รองรับวิธีต่างๆ มากมายในการจัดการอาร์กิวเมนต์บรรทัดคำสั่ง มี หลาย ไลบรารีที่อำนวยความสะดวกในการแยกวิเคราะห์อาร์กิวเมนต์บรรทัดคำสั่ง

วิธีการในตัวคือการใช้ sys โมดูล. ในแง่ของชื่อและการใช้งาน เกี่ยวข้องโดยตรงกับไลบรารี C (libc).

วิธีที่สองคือ getopt โมดูลซึ่งจัดการทั้งตัวเลือกแบบสั้นและแบบยาว รวมถึงการประเมินค่าพารามิเตอร์

พื้นที่ โมดูลอาร์กพาร์สซึ่งได้มาจาก optparse โมดูล (ใช้ได้จนถึง Python 2.7)

พื้นที่ docopt โมดูลซึ่งก็คือ ใช้ได้กับ GitHubและยังอนุญาตฟังก์ชันการทำงานเดียวกันอีกด้วย

เมื่อเร็ว ๆ นี้ absl ห้องสมุดก็ได้รับความนิยมเช่นกันเพื่อมาทดแทน optparse และ getopt().

แต่ละวิธีมีข้อดีและข้อเสียที่แตกต่างกัน ดังนั้นจึงควรประเมินแต่ละวิธีเพื่อดูว่าวิธีใดที่เหมาะกับความต้องการของคุณมากที่สุด

โมดูลระบบ

นี่คือโมดูลพื้นฐานที่จัดส่งมาพร้อมกับ Python ตั้งแต่สมัยแรกๆ ใช้แนวทางที่คล้ายกันมากกับการใช้ไลบรารี C argc/argv เพื่อเข้าถึงข้อโต้แย้ง ที่ โมดูลระบบ ใช้อาร์กิวเมนต์บรรทัดคำสั่งในโครงสร้างรายการแบบง่ายชื่อ sys.argv.

แต่ละองค์ประกอบรายการแสดงถึงอาร์กิวเมนต์เดียว รายการแรกในรายการคือ sys.argv[0]เป็นชื่อของสคริปต์ Python องค์ประกอบรายการที่เหลือ sys.argv[1] ไปยัง sys.argv[n]คืออาร์กิวเมนต์บรรทัดคำสั่ง 2 ถึง n

มีการใช้ช่องว่างเป็นตัวคั่นระหว่างอาร์กิวเมนต์ ค่าอาร์กิวเมนต์ที่มีช่องว่างจะต้องล้อมรอบด้วยเครื่องหมายคำพูดเพื่อให้สามารถแยกวิเคราะห์ได้อย่างเหมาะสม sys.

เทียบเท่ากับ argc เป็นเพียงจำนวนองค์ประกอบในรายการ หากต้องการรับค่านี้ ให้ใช้ Python len() ตัวดำเนินการ เราจะแสดงสิ่งนี้ในตัวอย่างโค้ดในภายหลัง

การพิมพ์อาร์กิวเมนต์ CLI แรก

ในตัวอย่างแรกนี้ สคริปต์ของเราจะกำหนดวิธีการเรียกสคริปต์ ข้อมูลนี้ถูกเก็บไว้ในอาร์กิวเมนต์บรรทัดคำสั่งแรกซึ่งจัดทำดัชนีด้วย 0 โค้ดด้านล่างแสดงวิธีที่คุณได้รับชื่อสคริปต์ Python ของคุณ:

import sys

print("The script has the name %s" % (sys.argv[0])

บันทึกรหัสนี้ในไฟล์ชื่อ arguments-program-name.pyแล้วเรียกตามภาพด้านล่างนี้ ผลลัพธ์จะเป็นดังนี้และมีชื่อไฟล์ รวมถึงเส้นทางแบบเต็ม:

$ python arguments-program-name.py
The script has the name arguments-program-name.py
$ python /home/user/arguments-program-name.py
The script has the name /home/user/arguments-program-name.py

อย่างที่คุณเห็นจากการเรียกครั้งที่สองด้านบน เราไม่เพียงแต่ได้รับชื่อของไฟล์ Python เท่านั้น แต่ยังรวมถึงเส้นทางแบบเต็มที่ใช้ในการเรียกมันด้วย

การนับจำนวนอาร์กิวเมนต์

ในตัวอย่างที่สองนี้ เราเพียงแค่นับจำนวนอาร์กิวเมนต์บรรทัดคำสั่งโดยใช้บิวท์อิน len() วิธี sys.argv เป็นรายการที่เราต้องตรวจสอบ ในโค้ดด้านล่าง เราได้รับจำนวนอาร์กิวเมนต์แล้วลบ 1 เนื่องจากหนึ่งในอาร์กิวเมนต์เหล่านั้น (เช่น อาร์กิวเมนต์แรก) ถูกกำหนดเป็นชื่อของไฟล์เสมอ ซึ่งไม่ได้มีประโยชน์สำหรับเราเสมอไป ดังนั้นจำนวนอาร์กิวเมนต์จริงที่ผู้ใช้ส่งผ่านคือ len(sys.argv) - 1:

import sys


arguments = len(sys.argv) - 1
print ("The script is called with %i arguments" % (arguments))

บันทึกและตั้งชื่อไฟล์นี้ arguments-count.py ตัวอย่างการเรียกสคริปต์นี้แสดงไว้ด้านล่าง ซึ่งรวมถึงสามสถานการณ์ที่แตกต่างกัน:

  • การโทรโดยไม่มีอาร์กิวเมนต์บรรทัดคำสั่งเพิ่มเติม
  • การโทรที่มีการโต้แย้งสองข้อ
  • การเรียกที่มีสองอาร์กิวเมนต์ โดยที่อาร์กิวเมนต์ที่สองเป็นสตริงที่มีเครื่องหมายคำพูดซึ่งมีช่องว่าง
$ python arguments-count.py
The script is called with 0 arguments
$ python arguments-count.py --help me
The script is called with 2 arguments
$ python arguments-count.py --option "long string"
The script is called with 2 arguments
วนซ้ำผ่านการโต้แย้ง

ตัวอย่างที่สามของเราส่งออกทุกอาร์กิวเมนต์ที่ส่งไปยังสคริปต์ Python ยกเว้นชื่อโปรแกรมเอง ดังนั้นเราจึงวนซ้ำอาร์กิวเมนต์บรรทัดคำสั่งที่ขึ้นต้นด้วย ที่สอง องค์ประกอบรายการ โปรดจำไว้ว่านี่คือดัชนี 1 เนื่องจากรายการเป็นแบบ 0 ใน Python:

import sys


arguments = len(sys.argv) - 1


position = 1
while (arguments >= position):
    print ("Parameter %i: %s" % (position, sys.argv[position]))
    position = position + 1

ด้านล่างนี้เราเรียกโค้ดของเรา ซึ่งบันทึกไว้ในไฟล์ arguments-output.py เช่นเดียวกับตัวอย่างก่อนหน้านี้ ผลลัพธ์จะแสดงการโทรที่แตกต่างกันสามแบบ:

  • การโทรโดยไม่มีข้อโต้แย้งใด ๆ
  • การโทรที่มีการโต้แย้งสองข้อ
  • การเรียกที่มีสองอาร์กิวเมนต์ โดยที่อาร์กิวเมนต์ที่สองเป็นสตริงที่มีเครื่องหมายคำพูดซึ่งมีช่องว่าง
$ python arguments-output.py
$ python arguments-output.py --help me
Parameter 1: --help
Parameter 2: me
$ python arguments-output.py --option "long string"
Parameter 1: --option
Parameter 2: long string

โปรดจำไว้ว่า จุดแสดงตัวอย่างสตริงที่ยกมาคือพารามิเตอร์มักจะคั่นด้วยช่องว่าง เว้นแต่ ล้อมรอบด้วยเครื่องหมายคำพูด

ธงโรยตัว (absl)

ไลบรารี Flags ของ Abseil มีจุดมุ่งหมายเพื่อนำอาร์กิวเมนต์บรรทัดคำสั่งมาสู่การผลิต โดยมีอาร์กิวเมนต์บรรทัดคำสั่งแบบกระจาย เมื่อโมดูลใช้แฟล็กบรรทัดคำสั่ง และนำเข้าไปยังโมดูลอื่น – โมดูลอื่น นำเข้าธงด้วยและสามารถประมวลผลได้โดยการส่งต่อไปยังโมดูลที่นำเข้า

ซึ่งทำให้การแชร์อาร์กิวเมนต์บรรทัดคำสั่งที่ซับซ้อนระหว่างโมดูลง่ายขึ้นและมีรายละเอียดน้อยลง

นอกจากนี้ ไลบรารียังช่วยให้คุณกำหนดค่าเริ่มต้น คำอธิบาย และประเภทข้อมูลของอาร์กิวเมนต์ได้ ดังนั้นจึงไม่จำเป็นต้องตรวจสอบและแปลงเพิ่มเติม

from absl import flags
import sys


flags.DEFINE_string('name', 'User', 'The name of the user.')


FLAGS = flags.FLAGS
FLAGS(sys.argv)

print(f"Hello {FLAGS.name}!")

ประเภทข้อมูลที่รองรับ ได้แก่ :

  • DEFINE_integer()
  • DEFINE_string()
  • DEFINE_bool()
  • DEFINE_enum()
  • DEFINE_list()
  • DEFINE_float()

ตลอดจน DEFINE_multi_integer(), DEFINE_multi_string() และ DEFINE_multi_enum() สำหรับการป้อนข้อมูลแบบหลายอาร์กิวเมนต์ นอกจากนี้การวิ่ง --help, --helpfullฯลฯ พิมพ์แฟล็กที่มีอยู่และคำอธิบายในรูปแบบที่แตกต่างกัน

ดูคู่มือเชิงปฏิบัติสำหรับการเรียนรู้ Git ที่มีแนวทางปฏิบัติที่ดีที่สุด มาตรฐานที่ยอมรับในอุตสาหกรรม และเอกสารสรุปรวม หยุดคำสั่ง Googling Git และจริงๆ แล้ว เรียน มัน!

ไลบรารียังอนุญาตให้คุณกำหนดการตรวจสอบความถูกต้อง ทั้งในแง่ของช่วง เช่น ค่าที่เป็นจำนวนเต็มซึ่งมี upper_bound or lower_bound เป็นที่ยอมรับและใช้วิธีการตามอำเภอใจเพื่อตรวจสอบค่า:

def validate_name(value):
    return len(value) > 15

flags.register_validator('name',
                         validate_name,
                         message='Name is over 15 characters long.',
                         flag_values=FLAGS)

รวบรวมสิ่งเหล่านี้ไว้เป็นตัวอย่างที่เป็นรูปธรรม:

from absl import flags
import sys

flags.DEFINE_string('name', 'User', 'The name of the user.')
flags.DEFINE_integer('tasks', 0, 'The number of tasks a user has.', lower_bound=0)

FLAGS = flags.FLAGS
FLAGS(sys.argv)

print(f"{FLAGS.name} has {FLAGS.tasks} tasks to work on.")
$ python flags.py --name=John --tasks=5
John has 5 tasks to work on.
$ python flags.py --name=John --tasks=-1

Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/absl/flags/_flag.py", line 180, in _parse
    return self.parser.parse(argument)
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/absl/flags/_argument_parser.py", line 168, in parse
    raise ValueError('%s is not %s' % (val, self.syntactic_help))
ValueError: -1 is not a non-negative integer
...

โมดูล argparse

พื้นที่ โมดูลอาร์กพาร์ส มีให้ใช้งานตั้งแต่ Python 3.2 และการปรับปรุงของ optparse โมดูลที่มีอยู่จนถึง Python 2.7 เอกสาร Python ประกอบด้วยคำอธิบาย API และบทช่วยสอนที่ครอบคลุมวิธีการทั้งหมดโดยละเอียด

โมดูลนำเสนออินเทอร์เฟซบรรทัดคำสั่งพร้อมเอาต์พุตมาตรฐาน ในขณะที่ทั้งสองโซลูชันก่อนหน้านี้ปล่อยให้งานส่วนใหญ่อยู่ในมือคุณ argparse อนุญาตให้มีการตรวจสอบอาร์กิวเมนต์แบบคงที่และแบบเป็นทางเลือก โดยการตรวจสอบชื่อเป็นแบบสั้นหรือแบบยาว เนื่องจากเป็นอาร์กิวเมนต์ทางเลือกดีฟอลต์ ซึ่งจะรวมไว้ด้วย -hพร้อมด้วยเวอร์ชันยาว --help- อาร์กิวเมนต์นี้มาพร้อมกับข้อความช่วยเหลือเริ่มต้นที่อธิบายอาร์กิวเมนต์ที่ยอมรับ

รหัสด้านล่างแสดงการเริ่มต้น parser และผลลัพธ์ด้านล่างที่แสดงการเรียกพื้นฐาน ตามด้วยข้อความช่วยเหลือ ตรงกันข้ามกับการเรียก Python ที่เราใช้ในตัวอย่างก่อนหน้านี้ โปรดจำไว้ว่าให้ใช้ Python 3 กับตัวอย่างเหล่านี้:


import argparse


parser = argparse.ArgumentParser()
parser.parse_args()
$ python3 arguments-argparse-basic.py 
$ python3 arguments-argparse-basic.py -h
usage: arguments-argparse-basic.py [-h]

optional arguments:
  -h, --help  show this help message and exit
$ python3 arguments-argparse-basic.py --verbose
usage: arguments-argparse-basic.py [-h]
arguments-argparse-basic.py: error: unrecognized arguments: --verbose

ในขั้นตอนถัดไป เราจะเพิ่มคำอธิบายที่กำหนดเองให้กับข้อความช่วยเหลือสำหรับผู้ใช้ของเรา การเริ่มต้น parser ด้วยวิธีนี้จะทำให้มีข้อความเพิ่มเติมได้ รหัสด้านล่างเก็บคำอธิบายไว้ใน text ตัวแปรซึ่งกำหนดไว้อย่างชัดเจนให้กับ argparse ชั้นเรียนเป็น description พารามิเตอร์. เรียกโค้ดด้านล่างนี้ คุณจะเห็นผลลัพธ์ที่มีลักษณะดังนี้:


import argparse


text = 'This is a test program. It demonstrates how to use the argparse module with a program description.'


parser = argparse.ArgumentParser(description=text)
parser.parse_args()
$ python3 arguments-argparse-description.py --help
usage: arguments-argparse-description.py [-h]

This is a test program. It demonstrates how to use the argparse module with a
program description.

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

ในขั้นตอนสุดท้าย เราจะเพิ่มอาร์กิวเมนต์ทางเลือกที่มีชื่อ -Vซึ่งมีอาร์กิวเมนต์รูปแบบยาวที่สอดคล้องกันชื่อ --version- ในการทำเช่นนั้นเราใช้วิธีการ add_argument() ที่เราเรียกด้วยพารามิเตอร์สามตัว (แสดงสำหรับ --version, เท่านั้น):

  • ชื่อของพารามิเตอร์: --version
  • ข้อความช่วยเหลือสำหรับพารามิเตอร์: help="show program version"
  • การดำเนินการ (ไม่มีมูลค่าเพิ่มเติม): action="store_true"

ซอร์สโค้ดที่แสดงด้านล่าง การอ่านอาร์กิวเมนต์ลงในตัวแปรที่เรียกว่า args จะทำผ่านทาง parse_args() วิธีการจาก parser วัตถุ. โปรดทราบว่าคุณส่งทั้งเวอร์ชันสั้นและเวอร์ชันยาวในการโทรครั้งเดียว สุดท้าย คุณตรวจสอบว่าคุณลักษณะ args.V or args.version ได้รับการตั้งค่าและส่งออกข้อความเวอร์ชัน:


import argparse


parser = argparse.ArgumentParser()
parser.add_argument("-V", "--version", help="show program version", action="store_true")


args = parser.parse_args()


if args.version:
    print("This is myprogram version 0.1")
$ python3 arguments-argparse-optional.py -V
This is myprogram version 0.1
$ python3 arguments-argparse-optional.py --version
This is myprogram version 0.1

พื้นที่ --version อาร์กิวเมนต์ไม่จำเป็นต้องระบุค่าในบรรทัดคำสั่ง นั่นเป็นเหตุผลที่เราตั้งค่าอาร์กิวเมนต์การดำเนินการเป็น "store_true"- ในกรณีอื่นๆ คุณอาจต้องกำหนดค่าเพิ่มเติม เช่น หากคุณระบุปริมาตร ความสูง หรือความกว้างที่แน่นอน สิ่งนี้แสดงในตัวอย่างถัดไป ในกรณีเริ่มต้น โปรดทราบว่าอาร์กิวเมนต์ทั้งหมดจะถูกตีความว่าเป็นสตริง:


import argparse


parser = argparse.ArgumentParser()


parser.add_argument("--width", "-w", help="set output width")


args = parser.parse_args()


if args.width:
    print("Set output width to %s" % args.width)

ที่นี่เราจะแสดงสิ่งที่เกิดขึ้นเมื่อส่งค่าอาร์กิวเมนต์ที่แตกต่างกัน ซึ่งรวมถึงเวอร์ชันสั้นและเวอร์ชันยาว รวมถึงข้อความช่วยเหลือ:

$ python3 arguments-argparse-optional2.py -w 10
Set output width to 10
$ python3 arguments-argparse-optional2.py --width 10
Set output width to 10
$ python3 arguments-argparse-optional2.py -h
usage: arguments-argparse-optional2.py [-h] [--width WIDTH]

optional arguments:
  -h, --help            show this help message and exit
  --width WIDTH, -w WIDTH
                        set output width

โมดูล getopt

ดังที่คุณอาจสังเกตเห็นมาก่อนว่า sys โมดูลแยกสตริงบรรทัดคำสั่งออกเป็นด้านเดียวเท่านั้น หลาม โมดูล getopt ขยายออกไปอีกเล็กน้อยและขยายการแยกสตริงอินพุตด้วยการตรวจสอบความถูกต้องของพารามิเตอร์ ขึ้นอยู่กับ getopt ฟังก์ชัน C อนุญาตให้ใช้ทั้งตัวเลือกแบบสั้นและแบบยาว รวมถึงการกำหนดค่า

ในทางปฏิบัตินั้นจำเป็นต้องมีการ sys โมดูลเพื่อประมวลผลข้อมูลอินพุตอย่างถูกต้อง โดยให้ทำทั้ง sys โมดูลและ getopt ต้องโหลดโมดูลไว้ก่อน ต่อไป จากรายการพารามิเตอร์อินพุต เราจะลบองค์ประกอบรายการแรก (ดูโค้ดด้านล่าง) และจัดเก็บรายการอาร์กิวเมนต์บรรทัดคำสั่งที่เหลือในตัวแปรที่เรียกว่า argument_list:


import getopt, sys


full_cmd_arguments = sys.argv


argument_list = full_cmd_arguments[1:]

print argument_list

ข้อโต้แย้งใน argument_list ตอนนี้สามารถแยกวิเคราะห์ได้โดยใช้ getopts() วิธี. แต่ก่อนจะทำอย่างนั้นเราต้องบอกก่อน getopts() เกี่ยวกับพารามิเตอร์ที่ถูกต้อง พวกเขาถูกกำหนดเช่นนี้:

short_options = "ho:v"
long_options = ["help", "output=", "verbose"]

ซึ่งหมายความว่าข้อโต้แย้งเหล่านี้เป็นข้อโต้แย้งที่เราถือว่าถูกต้อง พร้อมด้วยข้อมูลเพิ่มเติม:

------------------------------------------
long argument   short argument  with value
------------------------------------------
--help           -h              no
--output         -o              yes
--verbose        -v              no
------------------------------------------

คุณอาจสังเกตเห็นว่า o ตัวเลือกสั้นดำเนินการโดยลำไส้ใหญ่ :. สิ่งนี้จะบอก getopt ว่าตัวเลือกนี้ควรได้รับการกำหนดค่า

ตอนนี้ช่วยให้เราสามารถประมวลผลรายการข้อโต้แย้งได้ ที่ getopt() วิธีการต้องใช้พารามิเตอร์สามตัวในการกำหนดค่า - รายการอาร์กิวเมนต์จริงจาก argvตลอดจนตัวเลือกทั้งแบบสั้นและแบบยาวที่ถูกต้อง (แสดงในข้อมูลโค้ดก่อนหน้า)

การเรียกเมธอดนั้นถูกเก็บไว้ในคำสั่ง try-catch เพื่อครอบคลุมข้อผิดพลาดระหว่างการประเมิน ข้อยกเว้นจะเกิดขึ้นหากค้นพบอาร์กิวเมนต์ที่ไม่ได้เป็นส่วนหนึ่งของรายการตามที่กำหนดไว้ก่อนหน้านี้ สคริปต์ Python จะพิมพ์ข้อความแสดงข้อผิดพลาดไปที่หน้าจอ และออกด้วยรหัสข้อผิดพลาด 2:

try:
    arguments, values = getopt.getopt(argument_list, short_options, long_options)
except getopt.error as err:
    
    print (str(err))
    sys.exit(2)

สุดท้าย อาร์กิวเมนต์ที่มีค่าที่สอดคล้องกันจะถูกจัดเก็บไว้ในตัวแปรสองตัวที่มีชื่อ arguments และ values- ตอนนี้คุณสามารถประเมินตัวแปรเหล่านี้ในโค้ดของคุณได้อย่างง่ายดาย เราสามารถใช้ก for-loop เพื่อวนซ้ำรายการอาร์กิวเมนต์ที่รู้จัก หนึ่งรายการต่อจากรายการถัดไป


for current_argument, current_value in arguments:
    if current_argument in ("-v", "--verbose"):
        print ("Enabling verbose mode")
    elif current_argument in ("-h", "--help"):
        print ("Displaying help")
    elif current_argument in ("-o", "--output"):
        print (("Enabling special output mode (%s)") % (current_value))

ด้านล่างนี้คุณจะเห็นผลลัพธ์จากการรันโค้ดนี้ เราจะแสดงให้เห็นว่าโปรแกรมมีปฏิกิริยาอย่างไรกับอาร์กิวเมนต์ของโปรแกรมทั้งที่ถูกต้องและไม่ถูกต้อง:

$ python arguments-getopt.py -h
Displaying help
$ python arguments-getopt.py --help
Displaying help
$ python arguments-getopt.py --output=green --help -v
Enabling special output mode (green)
Displaying help
Enabling verbose mode
$ python arguments-getopt.py -verbose
option -e not recognized

การเรียกโปรแกรมของเราครั้งสุดท้ายอาจดูสับสนเล็กน้อยในตอนแรก เพื่อให้เข้าใจสิ่งนี้ คุณจำเป็นต้องรู้ว่าตัวเลือกชวเลข (บางครั้งเรียกว่าธง) สามารถใช้ร่วมกับขีดกลางเส้นเดียวได้ ช่วยให้เครื่องมือของคุณยอมรับตัวเลือกต่างๆ ได้ง่ายขึ้น เช่น การโทร python arguments-getopt.py -vh ก็เหมือนกับการโทร python arguments-getopt.py -v -h- ดังนั้นในการโทรครั้งสุดท้ายข้างต้น getopt โมดูลคิดว่าผู้ใช้พยายามจะผ่าน -e เป็นตัวเลือกซึ่งไม่ถูกต้อง

สรุป

ในบทความนี้ เราได้แสดงวิธีการต่างๆ มากมายในการดึงอาร์กิวเมนต์บรรทัดคำสั่งใน Python รวมถึงการใช้ด้วย sys, getoptและ argparse- โมดูลเหล่านี้มีฟังก์ชันการทำงานที่แตกต่างกันออกไป บางส่วนให้มากกว่าโมดูลอื่นๆ มาก sys มีความยืดหยุ่นอย่างเต็มที่ ในขณะที่ทั้งสองอย่าง getoptและ argparse จำเป็นต้องมีโครงสร้างบางอย่าง ในทางตรงกันข้าม พวกเขาครอบคลุมงานที่ซับซ้อนส่วนใหญ่ sys ขึ้นอยู่กับคุณ หลังจากดำเนินการตามตัวอย่างที่ให้ไว้แล้ว คุณควรจะสามารถกำหนดได้ว่าโมดูลใดเหมาะสมกับโครงการของคุณมากที่สุด

ในบทความนี้ เราไม่ได้พูดถึงวิธีแก้ปัญหาอื่นๆ เช่น docopts โมดูล เราเพิ่งพูดถึงมัน โมดูลนี้ใช้แนวทางที่แตกต่างไปจากเดิมอย่างสิ้นเชิง และจะมีการอธิบายโดยละเอียดในบทความถัดไป

อ้างอิง

ประทับเวลา:

เพิ่มเติมจาก สแต็ค