ในการจัดการอาร์กิวเมนต์บรรทัดคำสั่งใน Python ให้ใช้โมดูล argv หรือ argparse ของโมดูล sys
โมดูล argparse ช่วยให้สามารถจัดการอาร์กิวเมนต์บรรทัดคำสั่งได้อย่างยืดหยุ่น แต่ต้องใช้ความระมัดระวังเมื่อจัดการกับค่าบูลีน (จริง เท็จ)
ข้อมูลต่อไปนี้มีให้ที่นี่
- argparse สำหรับนิยามอาร์กิวเมนต์อย่างง่าย
- ระบุประเภทของอาร์กิวเมนต์ (type) ด้วยargparse
- อย่าระบุ “bool” เป็นประเภทอาร์กิวเมนต์ของ add_argument()
- คำพิพากษาโดย bool()
- ใช้การดำเนินการอาร์กิวเมนต์แทนประเภทอาร์กิวเมนต์
- การใช้ฟังก์ชัน strtobool()
argparse สำหรับนิยามอาร์กิวเมนต์อย่างง่าย
โมดูล argparse ทำให้ง่ายต่อการกำหนดอาร์กิวเมนต์บรรทัดคำสั่ง
โมดูล argparse ทำให้ง่ายต่อการสร้างอินเทอร์เฟซบรรทัดคำสั่งที่ใช้งานง่าย คุณกำหนดอาร์กิวเมนต์ที่โปรแกรมของคุณต้องการ และ argparse จะค้นหาวิธีแยกวิเคราะห์ตัวเลือกเหล่านั้นจาก sys.argv โมดูล argparse จะสร้างความช่วยเหลือและข้อความการใช้งานโดยอัตโนมัติ และทำให้เกิดข้อผิดพลาดหากผู้ใช้ระบุอาร์กิวเมนต์ที่ไม่ถูกต้องให้กับโปรแกรม ข้อผิดพลาดเมื่อผู้ใช้ระบุอาร์กิวเมนต์ที่ไม่ถูกต้องกับโปรแกรม
argparse — Parser for command-line options, arguments and sub-commands — Python 3.10.0 Documentation
ระบุประเภทของอาร์กิวเมนต์ (type) ด้วยargparse
คุณลักษณะที่มีประโยชน์ของ argparse คือการระบุประเภท (ประเภท)
ตัวอย่างเช่น หากคุณระบุประเภทจำนวนเต็ม (int) อาร์กิวเมนต์จะแปลงอาร์กิวเมนต์เป็น int โดยอัตโนมัติและยังทำให้เกิดข้อผิดพลาดสำหรับอาร์กิวเมนต์ที่ไม่ใช่ int
ประเภทถูกระบุโดยประเภทอาร์กิวเมนต์ของ add_argument()
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('arg_int', type=int)
args = parser.parse_args()
print(args.arg_int)
print(type(args.arg_int))
เรียกใช้ไฟล์นี้จากบรรทัดคำสั่ง
$ python argparse_type_int.py 100
100
<type 'int'>
อาร์กิวเมนต์ 100 อ่านเป็น int
หากใช้ค่าที่ไม่ใช่ int เป็นอาร์กิวเมนต์ จะเกิดข้อผิดพลาดขึ้น
$ python argparse_type_int.py foo
usage: argparse_type_int.py [-h] arg_int
argparse_type_int.py: error: argument arg_int: invalid int value: 'foo'
$ python argparse_type_int.py 1.23
usage: argparse_type_int.py [-h] arg_int
argparse_type_int.py: error: argument arg_int: invalid int value: '1.23'
มีประโยชน์มากสำหรับการเล่นอาร์กิวเมนต์ที่ไม่คาดคิด
อย่าระบุ “bool” เป็นประเภทอาร์กิวเมนต์ของ add_argument()
สิ่งสำคัญที่ควรทราบคือ bool เช่น int และ float จะไม่ทำงานตามที่คาดไว้ หากคุณระบุ bool เป็นประเภทอาร์กิวเมนต์ของ add_argument()
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('arg_bool', type=bool)
args = parser.parse_args()
print(args.arg_bool)
print(type(args.arg_bool))
เรียกใช้ไฟล์นี้จากบรรทัดคำสั่ง
$ python argparse_type_bool.py True
True
<type 'bool'>
ถ้า true ถูกใช้เป็นอาร์กิวเมนต์ ก็จะถูกอ่านว่าเป็น bool type true นี่เป็นลักษณะการทำงานที่คาดไว้ แต่ปัญหาคือกรณีต่อไปนี้
$ python argparse_type_bool.py False
True
<type 'bool'>
$ python argparse_type_bool.py bar
True
<type 'bool'>
หากคุณใช้เท็จหรือสตริงอื่นใดเป็นอาร์กิวเมนต์ จะถูกอ่านว่าเป็นจริง
สาเหตุที่สิ่งนี้เกิดขึ้นคือเมื่อระบุ type=xxx ใน add_argument() อาร์กิวเมนต์จะถูกส่งไปยัง xxx()
ตัวอย่างเช่น ถ้า type=int อาร์กิวเมนต์จะถูกส่งไปยัง int(); ถ้า type=float ให้ float()
เช่นเดียวกันกับ type=bool ซึ่งหมายความว่าอาร์กิวเมนต์จะถูกส่งไปยัง bool()
คำพิพากษาโดย bool()
bool() นี้เป็นสิ่งที่ยุ่งยาก
- bool() — Built-in Functions — Python 3.10.0 Documentation
- Truth Value Testing — Built-in Types — Python 3.10.0 Documentation
ค่าต่อไปนี้ถือเป็นเท็จ:
- None
- false
- ศูนย์ในประเภทตัวเลข ตัวอย่างเช่น ค่าต่อไปนี้
- 0
- 0
- 0j
- ลำดับที่ว่างเปล่า ตัวอย่างเช่น
- ‘
- ()
- []
- การทำแผนที่ว่างเปล่า ตัวอย่างเช่น
- {}
ค่าอื่นๆ ทั้งหมดจะถือว่าเป็นจริง ดังนั้นอ็อบเจกต์หลายประเภทจึงเป็นจริงเสมอ การดำเนินการและฟังก์ชันในตัวที่ส่งคืนผลลัพธ์บูลีนจะส่งคืนค่า 0 หรือ False เป็นค่าเท็จ และ 1 หรือ True เป็นค่าจริง เว้นแต่จะระบุไว้เป็นอย่างอื่น
ดังนั้นสตริงที่ไม่ว่างเปล่าทั้งหมดที่ส่งไปยัง bool() ไม่ว่าจะเป็น ‘จริง’ หรือ ‘เท็จ’ จะส่งกลับค่าจริง เฉพาะสตริงว่างเท่านั้นที่จะเป็นเท็จ
print(bool('True'))
print(bool('False'))
print(bool('abc'))
# True
# True
# True
print(bool(''))
# False
เมื่อตั้งค่า type=bool ใน add_argument() อาร์กิวเมนต์จะถูกส่งไปยัง bool() ดังนั้น ดังที่แสดงในตัวอย่างข้างต้น หากใช้ false เป็นอาร์กิวเมนต์ จะถูกแปลงโดย bool() เป็นสตริง ‘False’ และอ่านว่าเป็นจริง
ใช้การดำเนินการอาร์กิวเมนต์แทนประเภทอาร์กิวเมนต์
หากคุณต้องการใช้ค่าบูลีนใน argparse ให้ระบุ ‘store_true’ หรือ ‘store_false’ สำหรับการดำเนินการอาร์กิวเมนต์
- store_true’
- store_false’
สิ่งเหล่านี้จะเป็น ‘store_const’ รุ่นพิเศษที่จะจัดเก็บ True และ False ตามลำดับ นอกจากนี้ พวกเขาจะตั้งค่าเริ่มต้นเป็นเท็จและจริงตามลำดับ ตามลำดับนั้น
argparse — Parser for command-line options, arguments and sub-commands — Python 3.10.0 Documentation
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--en', action='store_true')
args = parser.parse_args()
print(args.en)
print(type(args.en))
ในตัวอย่างนี้--en
ดังนั้น หาก en ไม่ถูกตั้งค่าเป็นจริง จะถูกโหลดเป็น false ซึ่งเป็นค่าเริ่มต้นของ en
$ python argparse_option_bool.py --en
True
<type 'bool'>
$ python argparse_option_bool.py
False
<type 'bool'>
หากคุณต้องการตั้งค่าเริ่มต้นเป็น true และ false เมื่อเพิ่มตัวเลือก ให้ทำดังต่อไปนี้action='store_false'
การใช้ฟังก์ชัน strtobool()
หากคุณต้องการใช้อาร์กิวเมนต์ตำแหน่งแทนตัวเลือก คุณสามารถใช้ฟังก์ชัน strtobool() ได้
strtobool() เป็นฟังก์ชันที่แปลงสตริงเป็นจริง (1) หรือเท็จ (0)
แปลงสตริงบูลีนเป็นจริง (1) หรือเท็จ (0)
ค่าที่แท้จริงมีดังนี้
y
yes
true
on
1
ค่าเท็จมีดังนี้
n
no
f
false
off
0
หาก val ไม่เป็นไปตามข้างต้น จะทำให้เกิด ValueError
9. API Reference – strtobool() — Python 3.10.0 Documentation
ไม่คำนึงถึงขนาดตัวพิมพ์ ตัวอย่างเช่น คุณสามารถใช้สิ่งต่อไปนี้ สตริงอื่น ๆ จะส่งผลให้เกิดข้อผิดพลาด
TRUE'
True'
YES'
from distutils.util import strtobool
print(strtobool('true'))
print(strtobool('True'))
print(strtobool('TRUE'))
# 1
# 1
# 1
print(strtobool('t'))
print(strtobool('yes'))
print(strtobool('y'))
print(strtobool('on'))
print(strtobool('1'))
# 1
# 1
# 1
# 1
# 1
print(strtobool('false'))
print(strtobool('False'))
print(strtobool('FALSE'))
# 0
# 0
# 0
print(strtobool('f'))
print(strtobool('no'))
print(strtobool('n'))
print(strtobool('off'))
print(strtobool('0'))
# 0
# 0
# 0
# 0
# 0
# print(strtobool('abc'))
# ValueError: invalid truth value 'abc'
ชื่อคือ strtobool() แต่ค่าที่ส่งกลับไม่ใช่ bool แต่เป็น int (1 หรือ 0)
print(type(strtobool('true')))
# <class 'int'>
ตามที่เขียนไว้ก่อนหน้านี้ เมื่อระบุ type=xxx ใน add_argument() ของ argparse อาร์กิวเมนต์จะถูกส่งไปยัง xxx() ดังนั้นเราจึงสามารถทำสิ่งต่อไปนี้ได้type=strtobool
import argparse
from distutils.util import strtobool
parser = argparse.ArgumentParser()
parser.add_argument('arg_bool', type=strtobool)
args = parser.parse_args()
print(args.arg_bool)
print(type(args.arg_bool))
ค่าตอบแทนไม่ใช่ประเภทบูล แต่เป็น int ประเภท 1 หรือ 0 แต่สามารถอ่านค่าจริงหรือเท็จโดยมีค่าจริงหรือเท็จเป็นอาร์กิวเมนต์
$ python argparse_type_strtobool.py true
1
<type 'int'>
$ python argparse_type_strtobool.py false
0
<type 'int'>
นอกจากนี้ หากไม่คาดหวังอาร์กิวเมนต์ ข้อผิดพลาดจะถูกสร้างขึ้นอย่างเหมาะสม
$ python argparse_type_strtobool.py bar
usage: argparse_type_strtobool.py [-h] arg_bool
argparse_type_strtobool.py: error: argument arg_bool: invalid strtobool value: 'bar'