شرح مكتبة تحليل سطر الأوامر argparse
- ما هي مكتبة
argparse
- الخطوات الأساسية لمعالجة المدخلات في
argparse
- إنشاء أوامر فرعية في
argparse
- التعامل مع الأوامر التي لا تحتاج قيم
- تمرين حول المكتبة
argparse
ما هي مكتبة argparse
argparse
هي مكتبة مضمنة في بايثون، مما يعني أنها متاحة للاستخدام دون الحاجة إلى تثبيت أي حزم إضافية.
هذه المكتبة تساعد المطورين على إنشاء واجهات سطر أوامر سهلة الاستخدام و واضحة، مع توفير ميزات مثل:
- تحليل الوسائط و الخيارات.
- إنشاء رسائل مساعدة تلقائية.
- التحقق من صحة المدخلات.
- التعامل مع الأخطاء بشكل فعال.
من ناحية أخرى، تيح للمستخدمين التفاعل مع البرامج النصية من خلال سطر الأوامر ( Command Line )، مما يجعلها مثالية لإنشاء أدوات و أوامر مخصصة.
لاستخدام المكتبة عليك تضمينها أولاً كما يلي.
import argparse
الخطوات الأساسية لمعالجة المدخلات في argparse
1- إنشاء المحلل ( Parser ) باستخدام الكونستركتور argparse.ArgumentParser()
كما يلي.
مثال
# argparse هنا قمنا بتضمين المكتبة import argparse # parser هنا قمنا بإنشاء محلل إسمه parser = argparse.ArgumentParser(description='The description of your program')
في الباراميتر description
يجب وضع وصف مبسط للبرنامج الخاص.
2- إضافة الأوامر (الباراميترات) التي يمكن للمستخدم استعمالها عند تشغيل البرنامج باستخدام الدالة argparse.add_argument()
كما يلي.
مثال
# argparse هنا قمنا بتضمين المكتبة import argparse # parser هنا قمنا بإنشاء محلل إسمه parser = argparse.ArgumentParser(description='The description of your program') # parser هنا قمنا بتعريف 3 أوامر للمحلل parser.add_argument('-n', '--name', type=str, help="person's name", required=True) parser.add_argument('-a', '--age', type=int, help="person's age", required=True) parser.add_argument('-s', '--salary', type=int, help="person's salary", default=200)
المحلل الذي قمنا بتعريفه يتضمن ثلاث متغيرات هي name
و age
و salary
.
name
_ عندما يريد المستخدم تمرير قيمة لهذا الباراميتر عليه كتابة--name
أو-n
إختصاراً قبل وضع القيمة.type=str
تعني أن نوع القيمة التي يمكن تمريرها له هي نص.help
هي بمثابة معلومة مساعدة توضح لما يستعمل هذا الباراميتر.required=True
تعني أن تمرير قيمة لهذا الباراميتر هي أمر إجباري.age
_ عندما يريد المستخدم تمرير قيمة لهذا الباراميتر عليه كتابة--age
أو-a
إختصاراً قبل وضع القيمة.type=int
تعني أن نوع القيمة التي يمكن تمريرها له هي عدد صحيح.help
هي بمثابة معلومة مساعدة توضح لما يستعمل هذا الباراميتر.required=True
تعني أن تمرير قيمة لهذا الباراميتر هي أمر إجباري.salary
_ عندما يريد المستخدم تمرير قيمة لهذا الباراميتر عليه كتابة--salary
أو-s
إختصاراً قبل وضع القيمة.type=int
تعني أن نوع القيمة التي يمكن تمريرها له هي عدد صحيح.help
هي بمثابة معلومة مساعدة توضح لما يستعمل هذا الباراميتر.default=200
تعني قيمته الإفتراضية في حال لم تمرر له قيمة.
تمرير قيمة للمتغير salary
هو أمر إختياري لأننا عند تعريفه في المحلل لم نضع فيه الخاصية required=True
و احتياطاً قمنا بإعطائه 200
كقيمة إفتراضية لأنه في حال لم يقم المستخدم بتمرير قيمة له فإن قيمته ستكون None
.
3- تحليل القيم التي يمررها المستخدم للباراميترات باستخدام الدالة argparse.parse_args()
كما يلي.
مثال
# argparse هنا قمنا بتضمين المكتبة import argparse # parser هنا قمنا بإنشاء محلل إسمه parser = argparse.ArgumentParser(description='The description of your program') # parser هنا قمنا بتعريف 3 أوامر للمحلل parser.add_argument('-n', '--name', type=str, help="person's name", required=True) parser.add_argument('-a', '--age', type=int, help="person's age", required=True) parser.add_argument('-s', '--salary', type=int, help="person's salary", default=200) # args و تخزينها في كائن إسمه parser هنا قمنا بتحليل القيم المدخلة في المحلل args = parser.parse_args() # هنا قمنا بطباعة قيم المعطيات التي سيتم إدخالها مباشرةً لأننا ضمنّا أنه سيكون فيها قيم (سواء إجبارية أو افتراضية) print(f'Name: {args.name}') print(f'Age: {args.age}') print(f'Salary: {args.salary}')
4- لتشغيل البرنامج، إذهب إلى مساره و شغّل التيرمنال ( CMD ) في نفس المسار البرنامج. أو تستطيع استخدام سطر الأوامر الموجود في VSCode او PyCharm إلخ.. على حسب الطريقة التي تستعملها أنت.
الآن، إذا افترضنا أن إسم الملف الذي تكتب فيه الكود هو Test.py
فيمكنك تشغيله كما يلي.
مثال
python3 Test.py --name Waleed --age 29
النتيجة:
Age: 29
Salary: 200
لاحظ أن قيمة salary
هي 200
رغم أننا لم نمرر له قيمة أثناء تشغيل البرنامج و سبب ذلك أننا وضعنا له 200
كقيمة إفتراضية.
إنشاء أوامر فرعية في argparse
تستطيع إنشاء أوامر فرعية ( Subparsers ) مبنية على الأوامر الأساسية.
على سبيل المثال، تنشئ أمر add
لإضافة شخص و منه يتفرع أوامر أخرى كأمر لإدخال الإسم، أمر لإدخال العمر، أمر لإدخال الراتب إلخ..
إضافة أمر فرعي إلى المحلل، تعني أن المحلل يصبح لديه أمر يتفرع منه عدة أوامر خاصة به.
لإضافة الأوامر التي تسمح بإدخال قيم فرعية في المحلل نستخدم الدالة add_subparsers()
كما يلي.
مثال
# argparse هنا قمنا بتضمين المكتبة import argparse # parser هنا قمنا بإنشاء محلل إسمه parser = argparse.ArgumentParser(description='The description of your program') # command مهمته ترتيب الأوامر الفرعية في متغير إسمه sub_parser هنا قمنا بإنشاء محلل فرعي إسمه sub_parser = parser.add_subparsers(dest='command') # هنا قمنا بإنشاء أمر لإضافة شخص و هو يتضمن أمر فرعي لتحديد الإسم + أمر فرعي لتحديد العمر add_subparser = sub_parser.add_parser('add', help='for add a person') add_subparser.add_argument('-n', '--name', type=str, help="person's name", required=True) add_subparser.add_argument('-a', '--age', type=int, help="person's age", required=True) # هنا قمنا بإنشاء أمر لحذف الشخص و هو يتضمن أمر فرعي لتحديد إسم الشخص المراد حذفه remove_subparser = sub_parser.add_parser('remove', help='for remove a person') remove_subparser.add_argument('-n', '--name', type=str, help="person's name", required=True) # args و تخزينها في كائن إسمه parser هنا قمنا بتحليل الأوامر و القيم المدخلة في المحلل args = parser.parse_args() # سيتم طباعة أنه تم إضافة الشخص add هنا قمنا بالتحقق من الأمر الفرعي المستخدم، إذا كان if args.command == 'add': print(f'Person with name ({args.name}) and age ({args.age}) has been added!') # سيتم طباعة أنه تم حذف الشخص remove هنا قمنا بالتحقق من الأمر الفرعي المستخدم، إذا كان elif args.command == 'remove': print(f'Person with name ({args.name}) has been removed!') # help في حال لم يدخل المستخدم أي أمر فرعي فإنه سيتم طباعة النصوص الموضوعة في الخصائص else: parser.print_help()
تحليل طريقة عمل الكود
- في البداية سيتم إنشاء المحلل الأساسي كما تعلمنا سابقاً.
- سيتم إنشاء محلل للأوامر الفرعية مهمته تخزين أي أمر فرعي يدخله المستخدم في متغير إسمه
command
. - إنشاء أول أمر إسمه
add
و شرحنا أنه يستخدم لإضافة شخص في الخاصيةhelp
. - إنشاء أوامر فرعية من الأمر
add
، الأول هو الأمر--name
الذي يستقبل نص و هو أمر فرعي إجباري و الثاني الأمر--age
الذي يستقبل عدد صحيح و هو أمر فرعي إجباري أيضاً. - إنشاء أول أمر إسمه
remove
و شرحنا أنه يستخدم لحذف شخص في الخاصيةhelp
. - إنشاء أمر فرعي من الأمر
remove
، و هو الأمر--name
الذي يستقبل نص و هو أمر فرعي إجباري. - تحليل الأوامر و القيم المدخلة بواسطة الدالة
parse_args()
. - التحقق من مدخلات المستخدم، إن أدخل الأمر
add
سيتم طباعة أنه تم إضافة الشخص، و إن أدخل الأمرremove
سيتم طباعة أنه تم إضافة الشخص، في حال أدخل أمر فرعي غير موجود أو لم يدخل أي أمر فرعي (إجباري) فإنه سيتم طباعة الإرشادات الموضوعة في الخاصيةhelp
التابعة لكل أمر فرعي.
طريقة استخدام الأوامر الفرعية
الآن سنفترض أن إسم الملف الذي يوجد فيه الكود هو Test.py
و سنجرب الأوامر الأساسية و الفرعية الموجودة فيه.
في المثال التالي قمنا باستعمال الأمر add
لإضافة مستخدم، و ضمنه الأمر الفرعي --name
لتحديد إسمه و الأمر الفرعي --age
لتحديد عمره.
مثال
python3 test.py add --name Waleed --age 29
النتيجة:
في المثال التالي قمنا باستعمال الأمر remove
لحذف مستخدم، و ضمنه الأمر الفرعي --name
لتحديد إسمه.
مثال
python3 test.py remove --name Waleed
النتيجة:
التعامل مع الأوامر التي لا تحتاج قيم
في حال كان لديك مصفوفة تحتوي على أسماء و أردت عمل برنامج يقوم بتخيير المستخدم بأن يطبع كل ما بداخلها أو يتم طباعة فقط من لديه إسم محدد منهم. هنا عندما يقوم المستخدم بتشغيل البرنامج سيكون مخيّر على إعطاؤه أمر و قيمة، أو إعطاؤه أمر فقط بدون قيمة.
لتعريف أمر في argparse
لا يتطلب استعماله تمرير قيمه له يجب إعطاؤه الخاصية action="store_true"
فقط.
في المثال التالي، عند تشغيل البرنامج إذا قام المستخدم باستعمال الأمر --name
فإنه سيكون عليه تمرير قيمة نصية له و التي ستمثل إسم الشخص الذي يريد البحث عنه، أما عند استعمال الأمر --all
فإنه لا يجب تمرير قيم له لأنه سيتم طباعة أسماء جميع الأشخاص.
مثال
# argparse هنا قمنا بتضمين المكتبة import argparse # هنا قمنا بتعريف مصفوفة الأسماء التي سيتم البحث فيها names = ['waleed', 'ahmed', 'saeed', 'hala', 'ali', 'abeer'] # parser هنا قمنا بإنشاء محلل إسمه parser = argparse.ArgumentParser(description='The description of your program') # هنا قمنا بإنشاء أمر لعرض معلومات شخص محدد و أمر لعرض معلومات الجميع parser.add_argument('-n', '--name', help="person's name", type=str) parser.add_argument('-a', '--all', help='view all names', action="store_true") # args و تخزينها في كائن إسمه parser هنا قمنا بتحليل الأوامر و القيم المدخلة في المحلل args = parser.parse_args() # سيتم طباعة ما إذا كان الشخص المذكور إسمه موجود أم لا --name هنا قمنا بالتحقق من الأمر المستخدم، إذا كان if args.name: found = False for name in names: if args.name == name: print(f'({args.name}) exists!') found = True break if not found: print(f'({args.name}) does not exist!') # سيتم طباعة أسماء جميع الشخص --all إذا كان الأمر المستخدم هو elif args.all: for name in names: print(name) # help في حال لم يدخل المستخدم أي أمر فإنه سيتم طباعة النصوص الموضوعة في الخصائص else: parser.print_help()
طريقة تشغيل البرنامج
الآن سنفترض أن إسم الملف الذي يوجد فيه الكود هو Test.py
و سنجرب الأوامر الموجودة فيه.
في المثال التالي قمنا باستعمال الأمر --name
للبحث عن مستخدم من واحد من خلال إسمه.
مثال
python3 test.py --name waleed
النتيجة:
في المثال التالي قمنا باستعمال الأمر --all
لطباعة جميع المستخدمين.
مثال
python3 test.py --all
النتيجة:
ahmed
saeed
hala
ali
abeer
تمرين حول المكتبة argparse
إذهب لقسم التحديات البرمجية في موقع هرمش، و من ثم إلى تراكيب البيانات ثم إختر التحدي الأول (الخاص ببناء مكتبة).
إجعل المستخدم يتعامل مع البرنامج من خلال أوامر أنت تحددها له كإضافة كتاب أو حذف كتاب إلخ..