Berhati-hati apabila berurusan dengan nilai Boolean dalam argparse Python

Perniagaan

Untuk mengendalikan argumen baris arahan dalam Python, gunakan modul argv atau argparse modul sys.

Modul argparse membenarkan pengendalian hujah baris arahan yang fleksibel, tetapi berhati-hati mesti diambil apabila berurusan dengan nilai Boolean (benar, palsu).

Maklumat berikut disediakan di sini.

  • argparse untuk definisi hujah yang mudah
  • Nyatakan jenis hujah (jenis) dengan argparse
  • Jangan nyatakan “bool” sebagai jenis hujah add_argument()
  • Penghakiman oleh bool()
  • Gunakan tindakan hujah dan bukannya jenis hujah.
  • Menggunakan fungsi strtobool().

argparse untuk definisi hujah yang mudah

Modul argparse memudahkan untuk menentukan hujah baris arahan.

Modul argparse memudahkan untuk mencipta antara muka baris arahan yang mesra pengguna. Anda mentakrifkan hujah yang diperlukan oleh program anda dan argparse akan memikirkan cara menghuraikan pilihan tersebut daripada sys.argv. modul argparse secara automatik menjana mesej bantuan dan penggunaan, dan menimbulkan ralat jika pengguna menentukan hujah tidak sah kepada program. ralat apabila pengguna menentukan argumen tidak sah kepada atur cara.
argparse — Parser for command-line options, arguments and sub-commands — Python 3.10.0 Documentation

Nyatakan jenis hujah (jenis) dengan argparse

Ciri berguna argparse adalah untuk menentukan jenis (jenis).

Sebagai contoh, jika anda menentukan jenis integer (int), ia akan menukar argumen secara automatik kepada int dan juga menimbulkan ralat untuk argumen yang bukan int.

Jenis ditentukan oleh jenis argumen 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))

Jalankan fail ini dari baris arahan.

$ python argparse_type_int.py 100
100
<type 'int'>

Hujah 100 dibaca sebagai int.

Jika nilai bukan int digunakan sebagai hujah, ralat akan berlaku.

$ 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'

Sangat berguna untuk memainkan hujah yang tidak dijangka.

Jangan nyatakan “bool” sebagai jenis hujah add_argument()

Adalah penting untuk ambil perhatian bahawa bool, seperti int dan float, tidak akan berfungsi seperti yang diharapkan jika anda menentukan bool sebagai jenis hujah 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))

Jalankan fail ini dari baris arahan.

$ python argparse_type_bool.py True
True
<type 'bool'>

Jika benar digunakan sebagai hujah, ia akan dibaca sebagai jenis bool benar. Ini adalah tingkah laku yang diharapkan, tetapi masalahnya ialah kes berikut.

$ python argparse_type_bool.py False
True
<type 'bool'>

$ python argparse_type_bool.py bar
True
<type 'bool'>

Jika anda menggunakan false atau mana-mana rentetan lain sebagai hujah, ia akan dibaca sebagai benar.

Sebab mengapa ini berlaku ialah apabila type=xxx dinyatakan dalam add_argument(), argumen dihantar ke xxx().

Sebagai contoh, jika type=int, hujah akan dihantar ke int(); jika type=float, maka float().

Perkara yang sama berlaku untuk type=bool, yang bermaksud hujah akan dihantar ke bool().

Penghakiman oleh bool()

Bool() ini adalah yang rumit.

Nilai berikut dianggap palsu:

  • None
  • false
  • Sifar dalam jenis angka. Sebagai contoh, nilai berikut
    • 0
    • 0
    • 0j
  • Urutan kosong. Sebagai contoh
    • ()
    • []
  • Pemetaan kosong. Sebagai contoh
    • {}

Semua nilai lain diandaikan benar – oleh itu objek daripada pelbagai jenis sentiasa benar. Operasi dan fungsi terbina dalam yang mengembalikan hasil Boolean sentiasa mengembalikan 0 atau False sebagai nilai palsu dan 1 atau True sebagai nilai sebenar, melainkan dinyatakan sebaliknya.

Oleh itu, semua rentetan bukan kosong yang dihantar ke bool(), sama ada ‘true’ atau ‘false’, akan kembali benar. Hanya rentetan kosong akan menjadi palsu.

print(bool('True'))
print(bool('False'))
print(bool('abc'))
# True
# True
# True

print(bool(''))
# False

Apabila type=bool ditetapkan dalam add_argument(), hujah dihantar ke bool(). Oleh itu, seperti yang ditunjukkan dalam contoh di atas, jika false digunakan sebagai hujah, ia akan ditukar oleh bool() sebagai rentetan ‘False’ dan dibaca sebagai benar.

Gunakan tindakan hujah dan bukannya jenis hujah.

Jika anda ingin menggunakan nilai Boolean dalam argparse, nyatakan ‘store_true’ atau ‘store_false’ untuk tindakan hujah.

  • store_true’
  • store_false’

Ini akan menjadi versi khas ‘store_const’ yang akan menyimpan True dan False masing-masing. Selain itu, mereka akan menetapkan nilai lalai masing-masing kepada False dan True, dalam susunan tersebut.
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))

Dalam contoh ini, pilihan berikut diberikan.
--enOleh itu, jika en tidak ditetapkan sebagai benar, ia akan dimuatkan sebagai palsu, yang merupakan nilai lalai en.

$ python argparse_option_bool.py --en
True
<type 'bool'>

$ python argparse_option_bool.py
False
<type 'bool'>

Jika anda ingin menetapkan lalai kepada benar, dan palsu apabila pilihan itu ditambahkan, cuma lakukan perkara berikut.
action='store_false'

Menggunakan fungsi strtobool().

Jika anda ingin menggunakan argumen kedudukan dan bukannya pilihan, anda juga boleh menggunakan fungsi strtobool().

strtobool() ialah fungsi yang menukar rentetan kepada benar (1) atau palsu (0).

Menukar rentetan boolean kepada benar (1) atau palsu (0).
Nilai sebenar adalah seperti berikut

  • y
  • yes
  • true
  • on
  • 1

Nilai palsu adalah seperti berikut.

  • n
  • no
  • f
  • false
  • off
  • 0

Jika val bukan mana-mana di atas, ia menimbulkan ValueError.

9. API Reference – strtobool() — Python 3.10.0 Documentation

Ia tidak sensitif huruf besar-besaran, jadi sebagai contoh, anda boleh menggunakan yang berikut; sebarang rentetan lain akan mengakibatkan ralat.

  • 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'

Namanya strtobool(), tetapi nilai pulangannya bukan bool, tetapi int (1 atau 0).

print(type(strtobool('true')))
# <class 'int'>

Seperti yang ditulis sebelum ini, apabila type=xxx dinyatakan dalam add_argument() argparse, hujah akan dihantar kepada xxx(). Oleh itu, kita boleh melakukan perkara berikut.
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))

Nilai pulangan bukan jenis bool, tetapi jenis int 1 atau 0, tetapi ia boleh membaca nilai benar atau salah dengan benar atau salah sebagai argumen.

$ python argparse_type_strtobool.py true
1
<type 'int'>

$ python argparse_type_strtobool.py false
0
<type 'int'>

Juga, jika hujah tidak dijangka, ralat akan dijana dengan betul.

$ 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'