الدليل الشامل لوحدة argparse في بايثون

في بايثون، تعد argparse واحدة من تلك الوحدات التي يمكن أن تساعدك على كتابة تعليمات برمجية أكثر احترافية وذات مظهر أفضل. وذلك لأن argparse يجعل من السهل كتابة واجهات سطر أوامر سهلة الاستخدام. بحلول نهاية هذه المقالة، ستكون قد اكتسبت معرفة قوية بوحدة argparse، ويمكنك أيضًا استخدام المقالة كورقة غش.

هل أنت جاهز؟ دعونا ندخل في هذا الأمر مباشرة!

في هذا الدليل، دعونا نرى ما إذا كان بإمكاننا تحميل صورة باستخدام OPENCV من سطر الأوامر.

OpenCV هي مكتبة رؤية حاسوبية شائعة جدًا. تقوم بمهام مختلفة لمعالجة الصور واكتشاف الكائنات وما إلى ذلك. هنا، سنستخدمه للحصول على بعض الأمثلة المرئية لتشغيل برنامج نصي من سطر الأوامر باستخدام وحدة argparse.

يمكنك تثبيت OpenCV مباشرةً باستخدام pip:

pip install OpenCV-python 

نظرًا لأننا لا نحتاج إلى تثبيت argparse، فنحن جاهزون للبدء.

لا تتردد في اختيار صورة من اختيارك أثناء اتباع هذا الدليل. لقد التقطت صورة من UNSPLASH وأعدت تسميتها إلى 001.jpg لتسهيل العمل معها. إذا كنت تفضل استخدام بايثون لتنزيل ملف مباشرةً، فيمكنك معرفة كيفية القيام بذلك هنا.

واجهة سطر الأوامر التي سنقوم ببنائها

أولاً، لنبدأ ببرنامج نصي إما لتحميل صورة أو قلبها حول المحور السيني في OpenCV. نريد تشغيل هذا من سطر الأوامر. باختصار، سيستدعي البرنامج النصي التابعين imread() وimshow() من OpenCV لقراءة الصورة وعرضها.

سنضيف أيضًا خيار استدعاء التابع flip() من OpenCV لقلب الصورة رأسيًا. سيتم ذلك باستخدام عبارة if-else. إذا استخدمت الوسيطة --flip، فسيكون الإخراج هو الصورة المعكوسة؛ وإلا فإنه سيتم عرض الصورة ببساطة.

لقد قمت بإنشاء ملف باسم Display_img_opencv.py يحتوي على الكود التالي:

import cv2
import argparse
 
# Construct the argument parser and parse the arguments
arg_desc = '''\
        Let's load an image from the command line!
        --------------------------------
            This program loads an image
            with OpenCV and Python argparse!
        '''
parser = argparse.ArgumentParser(formatter_class = argparse.RawDescriptionHelpFormatter,
                                    description= arg_desc)
 
parser.add_argument("-i", "--image", metavar="IMAGE", help = "Path to your input image")
parser.add_argument("-f", "--flip", metavar="IMAGE_FLIP", help = "Path to your input image")
args = vars(parser.parse_args())
 
 
if args["flip"]:
    # Flip the image vertically
    print("[INFO] flipping image vertically...")
    flipped = cv2.imread(args["flip"])
    flip_img = cv2.flip(flipped, 0)
    
    # Display the flipped image and press any key to stop
    cv2.imshow("Flipped vertically", flip_img)
    
else:
    # Load the image with "cv2.imread"
    image = cv2.imread(args["image"])
    # Display the original image
    cv2.imshow("Image", image)
 
cv2.waitKey(0)

بعد ذلك يمكننا تشغيل البرنامج النصي باستخدام:

python display_img_opencv.py --image 001.jpg

وهذه هي النتيجة:

أو يمكننا قلب الصورة عموديًا باستخدام تعليمات سطر الأوامر التالية:

python display_img_opencv.py --flip 001.jpg

ونتيجة لذلك، انقلبت صورتنا الأولية حول المحور السيني.

يمكنك إيقاف البرنامج النصي بالضغط على أي مفتاح. لا تتردد في تجربته مع صورتك الخاصة.

الآن، دعونا نشرح كيفية بناء واجهة سطر الأوامر باستخدام وحدة argparse.

في هذا القسم، سوف نتعلم العملية خطوة بخطوة لبناء واجهة سطر الأوامر باستخدام وحدة بايثون argparse.

إضافة وصف البرنامج النصي باستخدام argparse

الخطوة الأولى هي إنشاء كائن ArgumentParser للاحتفاظ بجميع المعلومات اللازمة لتحليل سطر الأوامر إلى بايثون قبل تعيين المحلل اللغوي باستخدام التابع parse_args().

ملاحظة: نحتاج هنا إلى تغليف التابع parse_args() بالتابع vars() لتجنب حدوث خطأ. يمكنك الرجوع إلى قسم مساحة الاسم في وثائق PYTHON لمزيد من التوضيحات.

بعد ذلك، نضيف أيضًا وصفًا إلى كائن ArgumentParser لشرح باختصار ما يفعله البرنامج.

أسهل طريقة للقيام بذلك هي:

parser = argparse.ArgumentParser(description = "Load and flip an image with OpenCV")

ملاحظة: قد ترغب في الحصول على وصف منسق بشكل أفضل، حسب احتياجاتك.

في هذه الحالة، قمت بتعيين سلسلة الوصف الخاصة بي كمتغير يسمى arg_desc، ثم قمت بتمريره إلى ArgumentParser().

يتيح لي تعيين argparse.RawDescriptionHelpFormatter للمعلمة formatter_class تنسيق الوصف بالطريقة التي أريدها.

# Construct the argument parser and parse the arguments
arg_desc = '''\
        Let's load an image from the command line!
        --------------------------------
            This program loads an image
            with OpenCV and Python argparse!
        '''
parser = argparse.ArgumentParser(formatter_class = argparse.RawDescriptionHelpFormatter,
                                    description= arg_desc)

الحجج الموضعية في بايثون argparse

بعد ذلك، نحتاج إلى إضافة حجة موضعية. في هذه الحالة، لدينا وسيطتان، إحداهما لتحميل الصورة والأخرى لقلبها رأسيًا:

parser.add_argument("-i", "--image", metavar="IMAGE", help = "Path to your input image")
parser.add_argument("-f", "--flip", metavar="IMAGE_FLIP", help = "Path to your input image")

كان بإمكاني أيضًا كتابة سطور التعليمات البرمجية هذه على النحو التالي:

parser.add_argument("image", metavar="IMAGE", help = "Path to your input image")
parser.add_argument("flip", metavar="IMAGE_FLIP", help = "Path to your input image")

تسمى “image” و”flip” بالوسائط الموضعية وتشير إلى إجراء السمة. افتراضيًا، هذه هي المعلمة الأولى لـ add_argument().

ومع ذلك، يمكنك أيضًا توفير وسيطات اختيارية مع سلسلة من العلامات، كما فعلت في البرنامج النصي الأول. يتم تمييز هذه الوسيطات الاختيارية بـ - و -- كبادئات وتوفر بعض المرونة. يمكنهم استبدال الحجة الموضعية.

الوصول إلى قيم argparse

افتراضيًا، يستخدم ArgumentParser القيمة dest باعتبارها “اسم” لكل كائن، ولكن من الممكن توفير اسم بديل باستخدام metavar. ومع ذلك، لاحظ أنه يغير فقط الاسم المعروض في رسائل help (بدلاً من قيمة dest).

parser.add_argument("-i", "--image", metavar="IMAGE", help = "Path to your input image")
parser.add_argument("-f", "--flip", metavar="IMAGE_FLIP", help = "Path to your input image")

في هذه الحالة، قمت بتعيين metavar كـ “IMAGE” للقيمة dest الأولى و”IMAGE_FLIP” للقيمة الثانية.

إضافة مساعدة

بعد ذلك، يمكننا تعيين معلمة help لتقديم إرشادات حول كيفية استخدام البرنامج النصي الخاص بنا. في هذه الحالة، قمت بتعيين “المسار إلى صورة الإدخال الخاصة بك”. الآن، عندما أقوم بتشغيل تعليمات سطر الأوامر التالية:

python display_img_opencv.py --help

لدي الناتج التالي :

usage: display_img_opencv.py [-h] [-i IMAGE] [-f IMAGE_FLIP]                                                                                                                                                                                            Let's load an image from the command line!                                                                              --------------------------------                                                                                            This program loads an image                                                                                             with OpenCV and Python argparse!                                                                                                                                                                                                                                                                                                                            optional arguments:                                                                                                       -h, --help            show this help message and exit                                                                   -i IMAGE, --image IMAGE                                                                                                                       Path to your input image                                                                          -f IMAGE_FLIP, --flip IMAGE_FLIP 

في القسم التالي، سنستكشف كيفية تبديل القيمة الافتراضية للعلامة المنطقية.

تبديل القيم الافتراضية في argparse

تدعم بايثون نوعين من الوسائط: تلك ذات القيمة وتلك التي لا تحتوي على قيمة. على سبيل المثال، يمكنني إعادة كتابة وسيطتي الموضعية بقيمة افتراضية – في هذه الحالة، ملف الصورة الخاص بنا 001.jpg.

parser.add_argument("-i", "--image", metavar="IMAGE", default="001.jpg", help = "Path to your input image")
parser.add_argument("-f", "--flip", metavar="IMAGE_FLIP", help = "Path to your input image")

الآن، إذا قمت بتشغيل البرنامج النصي كـ…

python display_img_opencv.py

… سيعرض ملف الصورة 001.jpg.

من الممكن أيضًا أن يكون لديك وسيطة بدون قيمة. وفي هذه الحالة إما أن تكون الحجة موجودة أم لا.

لنأخذ مثالا آخر. نريد عرض صورة والحصول على معلومات حول هذه الصورة، مثل أبعادها وعدد القنوات. لكننا نريد هذه المعلومات فقط إذا تم تحديد --verbose. وإلا فإن البرنامج النصي سيعرض الصورة فقط دون إرجاع أي معلومات عنها.

import argparse
import cv2
 
# Construct the argument parser and parse the arguments
arg_desc = '''\
        Let's load an image from the command line!
        --------------------------------
            This program loads an image
            with OpenCV and Python argparse!
        '''
 
parser = argparse.ArgumentParser(formatter_class = argparse.RawDescriptionHelpFormatter,
                                    description= arg_desc)
 
parser.add_argument("-i", "--image", default="001.jpg", help = "Path to your input image")
parser.add_argument("-v", "--verbose", action="store_const", const=False, default=True, help = "Path to your input image")
args = vars(parser.parse_args())
 
# Load the image with "cv2.imread"
image = cv2.imread(args["image"])
# Dimensions, including width, height, and number of channels
(h, w, c) = image.shape[:3]
 
if args["verbose"]:
    
    # Display the image width, height, and number of channels  
    print("width: {} pixels".format(w))
    print("height: {}  pixels".format(h))
    print("channels: {}".format(c))
 
    # Display the image
    cv2.imshow("Image", image)
    
else:
    
    # Display the image
    cv2.imshow("Image", image)
 
cv2.waitKey(0)

تعني المعلمة action="store_const" أن قيمة الوسيطة هي كل ما تم تعيينه في المعلمة const عندما تكون الوسيطة موجودة. إذا لم تكن الوسيطة موجودة، فإنها تأخذ القيمة المحددة بواسطة المعلمة الافتراضية.

في السطر أعلاه، سيعرض البرنامج النصي الصورة والمعلومات المتعلقة بها بشكل افتراضي:

python load_img.py -i 001.jpg
width: 640 pixels
height: 427  pixels
channels: 3

والصورة:

يمكننا أيضًا أن نقرر عدم تحديد أي قيمة افتراضية. في هذه الحالة، ستكون المعلمة الافتراضية None. في هذا المثال، ستصبح حجتنا False:

parser.add_argument("-i", "--image", default="001.jpg", help = "Path to your input image")
parser.add_argument("-v", "--verbose", action="store_const", const=False, help = "Path to your input image")

سيؤدي تشغيل البرنامج النصي إلى عرض الصورة فقط، دون أي معلومات.

الآن، يمكنك أن ترى أن قيمة const وdefault عادةً ما تكونان متعارضتين في حالة الوسائط المنطقية.

لتسهيل التعامل معها، تمتلك بايثون إجراءات مختصرة تسمى store_true وstore_false. store_true يشبه const=True وdefault=False، بينما store_false هو العكس.

على سبيل المثال، يمكنني الحصول على معلومات حول الصورة بشكل افتراضي عن طريق تعيين action=store_false. وفيما يلي النص المعدل:

parser.add_argument("-i", "--image", default="001.jpg", help = "Path to your input image")
parser.add_argument("-v", "--verbose", action="store_false", help = "Path to your input image")

الآن، سيؤدي تشغيل البرنامج النصي إلى عرض الصورة بالإضافة إلى المعلومات المتعلقة بها.

إذا كنت ترغب في تعزيز مهاراتك في لغة بايثون، فلا تنس التحقق من مسار برمجة بايثون الخاص بنا. وسوف يساعدك على الوصول إلى أهدافك بشكل أسرع.

التعامل مع البيانات غير الصحيحة

لسبب ما، يمكنك إدخال وسائط غير صالحة كوسائط سطر الأوامر. في هذه الحالة، خطأ سوف يقتل البرنامج النصي. ومع ذلك، من الممكن تشغيل البرنامج النصي باستخدام الوسائط الصحيحة جزئيًا فقط.

إحدى الطرق للقيام بذلك هي إضافة وسيطة مع المعلمة nargs="*" لقبول أي عدد من الوسائط ثم إضافة قاموس للقيم المقبولة إلى parse_args() بدون شرطات.

parser.add_argument("-i", "--image", default="001.jpg", help = "Path to your input image")
parser.add_argument("-v", "--verbose", action='store_false', help = "Path to your input image")
parser.add_argument("remainder", nargs="*")
args = vars(parser.parse_args(["v", "i", "image", "verbose"]))

بهذه الطريقة، حتى إذا أدخلنا قيمًا غير صحيحة dest في الوحدة الطرفية، فسيستمر تشغيل البرنامج النصي الخاص بنا. هنا مثال:

python load_img.py world --cruel happy YEAH 

كما هو موضح سابقًا، يتجاهل البرنامج النصي القيم غير المعروفة ويظل يعمل.

ملاحظة: بمجرد دفع مشروعك إلى GitHub، لا تنس إضافة تعليمات سطر الأوامر في ملف README.md الخاص بك:

python display_img_opencv.py image 001.jpg

استخدام argparse مع Pathlib وJSON

الآن، دعونا نتحدث عن معلمة النوع. يتم تعيينه كـ str by default، ولكن يمكنك تغيير هذه القيمة إذا لزم الأمر.

في المثال أدناه، قمنا بتعيين type=int لأننا نريد حساب قيمة المكعب لعدد صحيح:

import argparse
 
parser = argparse.ArgumentParser()
parser.add_argument("cube", help="display a cube of a given number",
                    type=int)
args = parser.parse_args()
print(args.cube**3)

في المثال التالي، سنقوم بدمج Pathlib مع argparse لتغيير الدليل من سطر الأوامر.

import argparse
from pathlib import Path
 
parser = argparse.ArgumentParser()
parser.add_argument("--path", type=Path, default=Path(__file__).absolute().parent, help="Path to the target directory")
 
args = parser.parse_args()
print(args.path, type(args.path))

تأتي وسيطة سطر الأوامر كسلسلة؛ ستأخذ معلمة النوع دالة تقبل سلسلة وترجع قيمة. هنا، سيؤدي الإعداد type=Path إلى تحويل السلسلة إلى كائن Path.

إذا كنت مهتمًا بـ Pathlib، يمكنك قراءة المزيد عنه هنا.

لنفترض الآن أنك تريد تعيين قاموس كوسيطة اختيارية. يمكنك القيام بذلك باستخدام json.loads:

import json
import argparse
 
dict = '{"name": "img.jpg", "person": "Max", "flower": "tulip", "animal": "lion"}'
 
# Parse a dict
parser = argparse.ArgumentParser()
parser.add_argument('-i', '--input', type=json.loads)
args = parser.parse_args(['-i', dict])
print(args.input)

سيؤدي هذا إلى إرجاع ما يلي:

{'name': 'img.jpg', 'person': 'Max', 'flower': 'tulip', 'animal': 'lion'}

يمكنك معرفة المزيد عن JSON هنا. إذا كنت لا تعرف أي شيء عن العمل مع ملفات JSON في بايثون، فأنا أشجعك على الانضمام إلى دورتنا حول كيفية قراءة وكتابة ملفات JSON في بايثون.

يمكنك أيضًا استخدام argparse لإجراء تسلسل لأي فئة بيانات من/إلى JSON أو YAML.

أخيرًا وليس آخرًا، باستخدام argparse، يمكنك إضافة دعم لإجراء تسلسل/إلغاء تسلسل الأنواع المخصصة الخاصة بك.

ما الذي يمكنك فعله أيضًا باستخدام وحدة argparse؟

في هذا الدليل لوحدة argparse، تعلمنا كيفية إضافة واجهة سطر الأوامر إلى برنامج بايثون النصي. أنا أشجعك بشدة على تجربة الكود وإضافته إلى مشاريعك. وسوف تساهم بالكثير من القيمة، ولا تكلف الكثير.


اكتشاف المزيد من بايثون العربي

اشترك للحصول على أحدث التدوينات المرسلة إلى بريدك الإلكتروني.

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *

Scroll to Top

اكتشاف المزيد من بايثون العربي

اشترك الآن للاستمرار في القراءة والحصول على حق الوصول إلى الأرشيف الكامل.

Continue reading