في بايثون، تعد 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
، تعلمنا كيفية إضافة واجهة سطر الأوامر إلى برنامج بايثون النصي. أنا أشجعك بشدة على تجربة الكود وإضافته إلى مشاريعك. وسوف تساهم بالكثير من القيمة، ولا تكلف الكثير.
اكتشاف المزيد من بايثون العربي
اشترك للحصول على أحدث التدوينات المرسلة إلى بريدك الإلكتروني.