AzLearn

بناء أداة CLI

Building a CLI Tool

تطبيق ~25 دقيقة

بناء أداة CLI — Building a CLI Tool

أحد أقوى استخدامات Python هو بناء أدوات سطر الأوامر — برامج تشغّلها من الطرفية وتمرر لها معاملات مباشرةً. هذه الأدوات تُبنى بلغة Python في ثوانٍ وتعمل على كل نظام تشغيل. ستتعلم في هذا الدرس كيف تصنع أداة CLI احترافية خطوة بخطوة.

ملاحظة عن البيئة التفاعلية: الأمثلة التفاعلية هنا تعمل داخل المتصفح عبر Pyodide. لأن sys.argv في المتصفح لا يحمل معاملات حقيقية، نمرر المعاملات مباشرةً عبر parse_args([...]). هذا النمط مطابق تماماً لما يحدث على جهازك الحقيقي — الفرق الوحيد هو مصدر المعاملات.


sys.argv — المعاملات البسيطة

حين تشغّل برنامج Python من الطرفية، تصلك المعاملات عبر sys.argv — وهي قائمة (list) فيها اسم البرنامج أولاً ثم المعاملات التي مررتها:

python converter.py celsius 100

ما يصل إلى البرنامج:

sys.argv = ["converter.py", "celsius", "100"]
#            [0]              [1]         [2]

sys.argv[0] هو اسم البرنامج دائماً. المعاملات تبدأ من sys.argv[1].

جرّب هذا المثال التفاعلي — يُحاكي قراءة sys.argv ومعالجتها:

main.go

المشكلة مع sys.argv المباشر أنك تحتاج لمعالجة كل شيء يدوياً: التحقق من وجود المعاملات، تحويل الأنواع، طباعة رسالة المساعدة. لهذا أنشأت Python مكتبة argparse.


argparse — المعاملات الاحترافية

argparse مكتبة مدمجة في Python تمنحك:

  • معاملات موضعية (positional arguments): مطلوبة دائماً، بترتيب محدد
  • خيارات (optional arguments): تبدأ بـ -- أو -، لها قيم افتراضية
  • أعلام (flags): خيارات boolean مثل --verbose
  • رسالة مساعدة تلقائية: --help تُولَّد تلقائياً

بنية argparse الأساسية:

import argparse

# 1. أنشئ الـ parser — Create parser
parser = argparse.ArgumentParser(description="وصف الأداة")

# 2. عرّف المعاملات — Define arguments
parser.add_argument("name")                    # موضعي — positional
parser.add_argument("--age", type=int)         # خيار — optional
parser.add_argument("--verbose", action="store_true")  # علم — flag

# 3. حلّل المعاملات — Parse arguments
args = parser.parse_args(["أحمد", "--age", "25", "--verbose"])

# 4. استخدم النتائج — Use results
print(args.name)    # "أحمد"
print(args.age)     # 25  (تحوّل تلقائياً لـ int)
print(args.verbose) # True

جرّب مثالاً كاملاً:

main.go

أنواع وخيارات متقدمة

argparse يدعم أنواعاً وقيوداً متعددة:

الخاصيةالاستخدامالمعنى
type=int--count 5تحويل تلقائي لـ int
type=float--rate 3.14تحويل لـ float
default=Xغير موجوداستخدام X إذا لم يُمرر
required=Trueإجباري حتى لو يبدأ بـ --
choices=[...]--unit kmقبول قيم محددة فقط
action="store_true"--verboseTrue إذا وجد، False إذا غاب
nargs="+"--files a b cقبول قائمة من القيم

مثال على choices وtype:

main.go

مشروع: محوّل الوحدات — Unit Converter

لنبني أداة CLI كاملة تحوّل بين وحدات الحرارة والمسافة. هذا المشروع يجمع كل ما تعلمناه: معاملات موضعية، خيارات، choices، type=float.

منطق التحويل:

  • درجات حرارة: °C → °F: (C × 9/5) + 32 | °F → °C: (F - 32) × 5/9
  • مسافة: كيلومتر → ميل: km × 0.621371 | ميل → كيلومتر: miles × 1.60934
main.go

لاحظ أن argparse يحوّل --from-unit تلقائياً إلى args.from_unit (يستبدل - بـ _). هذا سلوك مقصود في المكتبة.


تشغيل الأداة على جهازك الحقيقي

احفظ الكود في ملف converter.py وشغّله:

# تحويل درجات الحرارة — Temperature conversion
python converter.py --from-unit C --to-unit F --value 100
# النتيجة: 100.00 C = 212.00 F

# تحويل المسافة — Distance conversion
python converter.py --from-unit km --to-unit mi --value 10
# النتيجة: 10.00 km = 6.21 mi

# طباعة المساعدة — Print help
python converter.py --help

argparse يولّد رسالة --help تلقائياً من الأوصاف التي كتبتها — هذا ما يجعل أدوات CLI الاحترافية واضحة وقابلة للاستخدام.


التحديات — Challenges

تحدي 1: معامل واحد

اكتب برنامجاً يقبل معاملاً موضعياً واحداً اسمه city ويطبع مرحباً من: <city>. مرر ["الرياض"] إلى parse_args.

تحدي — Challenge

تحدي 2: إضافة علم

أضف علماً اسمه --uppercase إلى برنامج التحية. إذا كان موجوداً، اطبع النص بأحرف كبيرة. مرر ["python", "--uppercase"] إلى parse_args. المتوقع: PYTHON.

تحدي — Challenge

تحدي 3: تحويل درجة الحرارة

اكتب برنامجاً يقبل درجة حرارة بالسيلسيوس (type=float) ويطبع مكافئها بالفهرنهايت. مرر ["--celsius", "0"] إلى parse_args. المتوقع: 32.0.

تحدي — Challenge

تحدي 4: محوّل المسافة الكامل

اكتب محوّلاً يقبل --km (float) ويطبع المسافة بالأميال. 1 km = 0.621371 miles. مرر ["--km", "10"] إلى parse_args. المتوقع: 6.21.

تحدي — Challenge