كن حذرًا عند التعامل مع القيم المنطقية في مناقشة بايثون

اعمال

للتعامل مع وسيطات سطر الأوامر في Python ، استخدم الوحدات النمطية argv أو argparse للوحدة النمطية sys.

تسمح الوحدة النمطية argparse بالتعامل المرن مع وسيطات سطر الأوامر ، ولكن يجب توخي الحذر عند التعامل مع القيم المنطقية (صواب ، خطأ).

يتم توفير المعلومات التالية هنا.

  • argparse للتعريف السهل للحجج
  • حدد نوع الوسيطة (النوع) باستخدام argparse
  • لا تحدد “منطقي” كنوع وسيطة لـ 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

حدد نوع الوسيطة (النوع) باستخدام 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'

مفيد جدا للعب الحجج غير المتوقعة.

لا تحدد “منطقي” كنوع وسيطة لـ add_argument ()

من المهم ملاحظة أن منطقيًا ، مثل int و float ، لن يعمل كما هو متوقع إذا حددت منطقيًا كنوع وسيطة لـ 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 كوسيطة ، فسيتم قراءتها كنوع منطقي صحيح. هذا هو السلوك المتوقع ، ولكن المشكلة هي الحالة التالية.

$ 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 ، فسيتم تعويم ().

وينطبق الشيء نفسه على type = bool ، مما يعني أنه سيتم تمرير الوسيطة إلى bool ().

حكم من قبل bool ()

هذا المنطقي () خادع.

تعتبر القيم التالية خاطئة:

  • None
  • false
  • صفر في الأنواع الرقمية. على سبيل المثال ، القيم التالية
    • 0
    • 0
    • 0j
  • تسلسل فارغ. على سبيل المثال
    • ()
    • []
  • تعيين فارغ. على سبيل المثال
    • {}

يُفترض أن تكون جميع القيم الأخرى صحيحة – وبالتالي فإن الكائنات ذات الأنواع المتعددة تكون صحيحة دائمًا. العمليات والدالات المضمنة التي تُرجع نتائج منطقية تُرجع دائمًا 0 أو خطأ كقيمة خاطئة و 1 أو True كقيمة حقيقية ، ما لم يُذكر خلاف ذلك.

لذلك ، فإن جميع السلاسل غير الفارغة التي تم تمريرها إلى bool () ، سواء كانت “true” أو “false” ، ستعيد صوابًا. فقط السلاسل الفارغة ستكون خاطئة.

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 على التوالي. بالإضافة إلى ذلك ، سيقومون بتعيين القيم الافتراضية على False و True على التوالي ، بهذا الترتيب.
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 على أنه true ، فسيتم تحميله على أنه false ، وهي القيمة الافتراضية لـ en.

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

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

إذا كنت تريد تعيين الإعداد الافتراضي على صواب ، وخطأ عند إضافة الخيار ، فما عليك سوى القيام بما يلي.
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 () ، ولكن القيمة المعادة ليست منطقية ، ولكن 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'