كيفية تحليل وسيطات سطر الأوامر في بايثون

هل تريد تشغيل نصوص Python باستخدام وسيطات سطر الأوامر؟ تعرف على كيفية تحليل وسيطات سطر الأوامر باستخدام الوحدات النمطية sys و getopt و argparse في Python.

في Python ، عندما تريد القراءة في إدخال المستخدم ، ستستخدم وظيفة الإدخال (). ومع ذلك ، بالنسبة لبعض التطبيقات ، قد ترغب في تمرير بعض الوسائط أثناء تشغيل البرنامج النصي في سطر الأوامر.

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

هيا نبدأ!

فهم sys.argv في بايثون

إذا كنت قد قمت ببرمجة لغة سي ، فأنت تعلم أن إحدى أبسط الطرق لتمرير الوسائط إلى البرنامج هي عبر سطر الأوامر. للقيام بذلك ، يمكنك هيكلة الوظيفة الرئيسية على النحو التالي:

#include<stdio.h>

int main(int argc, char **argv){
    //argc: argument count
    //argv: argument vector
    
    //do something on the args

    return 0;
}

هنا ، تشير argc إلى عدد الوسيطة وتقف argv على متجه الوسيطة.

تشغيل برامج Python النصية باستخدام وسيطات سطر الأوامر

في Python ، يمكنك تشغيل برنامج Python النصي في سطر الأوامر باستخدام python3 filename.py. عند القيام بذلك ، يمكنك أيضًا تمرير عدد عشوائي من وسيطات سطر الأوامر:

$ python3 filename.py arg1 arg2 ... argn

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

إليك مثال حيث نقوم بتشغيل main.py مع وسيطات سطر الأوامر:

$ python3 main.py hello world python script

يمكننا إجراء حلقة من خلال متجه الوسيطة باستخدام دالة loop و enumerate simple:

# main.py

import sys

for idx, arg in enumerate(sys.argv):
    print(f"arg{idx}: {arg}")
# Output
arg0:main.py
arg1:hello
arg2:world
arg3:python
arg4:script

نرى أن الوسيطة الأولى (في الفهرس 0) هي اسم ملف Python. وتبدأ الحجج اللاحقة في الفهرس 1.

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

  • كيف يعرف مستخدمو البرنامج الحجج التي يتعين عليهم تمريرها؟
  • وماذا تمثل هذه الحجج؟

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

تحليل وسيطة سطر الأوامر باستخدام getopt في Python

دعنا نتعلم كيفية تحليل وسيطات سطر الأوامر باستخدام وحدة getopt المدمجة.

  تعلم كيفية كتابة الكود بشكل أسرع مع مدرس الكتابة

بعد استيراد getopt من الوحدة النمطية getopt ، يمكنك تحديد الوسائط المراد تحليلها والخيارات القصيرة والخيارات الطويلة لتشغيل البرنامج النصي باستخدام. نحتاج إلى تحليل جميع الحجج بدءًا من الفهرس 1 في sys.argv. لذا فإن الشريحة المطلوب تحليلها هي sys.argv[1:].

هنا ، سنحتاج إلى سلسلة رسالة واسم ملف. دعنا نستخدم m و f ​​كخيارات قصيرة ورسالة وملف كخيارات طويلة.

ولكن كيف نضمن أن خيارًا معينًا يتطلب حجة؟

  • في الخيارات القصيرة ، يمكنك جعل الخيار يتطلب وسيطة عن طريق إضافة نقطتين (:) بعد اسم الخيار القصير.
  • وبالمثل ، في الخيارات الطويلة ، يمكنك إضافة علامة = بعد خيار الشراء الطويل. يمكننا التقاط هذه الخيارات والحجج الخاصة بكل منها.

بإضافة هذه ، سيكون لدينا الكود التالي في main.py:

# main.py

import sys
from getopt import getopt

opts, args = getopt(sys.argv[1:],'m:f:',['message=","file="])

print(opts)
print(args)

هنا ، يحتوي المتغير المختار على الخيارات والوسيطات كقائمة من المجموعات. سيتم جمع أي حجة موضعية أخرى نمررها في متغير args.

يمكننا تمرير الرسالة واسم الملف لتشغيل البرنامج النصي ، ويمكننا استخدام الخيارات القصيرة أو الخيارات الطويلة.

بتشغيل main.py باستخدام الخيارات الطويلة ، لدينا:

$ python3 main.py --message hello --file somefile.txt

لدينا الخيارات والحجج مثل tuple في متغير opts. نظرًا لأننا لم نجتاز أي حجة موضعية ، فإن args هي قائمة فارغة.

# Output
[("--message', 'hello'), ('--file', 'somefile.txt')]
[]

بالتساوي ، يمكننا أيضًا استخدام الخيارات القصيرة كما هو موضح:

$ python3 main.py -m hello -f somefile.txt
# Output
[('-m', 'hello'), ('-f', 'somefile.txt')]
[]

⚠️ لا يجب الخلط بين الخيار -m short في هذا المثال وبين علامة سطر الأوامر -m التي تُستخدم لتشغيل وحدة نمطية كوحدة نمطية رئيسية عند تشغيل برنامج نصي بايثون.

على سبيل المثال ، ستستخدم python3 -m unittest main.py لتشغيل unittest كوحدة نمطية رئيسية عند تشغيل main.py.

ذكرنا أن جميع الحجج الموضعية الأخرى التي نمررها سيتم جمعها في متغير args. هذا مثال:

$ python3 main.py -m hello -f somefile.txt another_argument

تحتوي قائمة args على الوسيطة الموضعية another_argument.

# Output
[('-m', 'hello'), ('-f', 'somefile.txt')]
['another_argument']

هنا ، توجد قائمة الخيارات. حتى نتمكن من المرور عبرها ، وفك ضغط tuple ، وسحب الوسيطات المقابلة للخيارات المحددة.

لكن ماذا سنفعل باسم الملف والرسالة بعد أن قمنا بمعالجة هذه الحجج؟ سنفتح الملف في وضع الكتابة ونكتب سلسلة الرسالة المحولة إلى أحرف كبيرة إلى الملف.

# main.py
import sys
from getopt import getopt

opts, args = getopt(sys.argv[1:],'m:f:',['message=","file="])

print(opts)
print(args)

for option, argument in opts:
    if option == "-m':
        message = argument
    if option == '-f':
        file = argument

with open(file,'w') as f:
    f.write(message.upper())

لنقم بتشغيل main.py مع الخيارات القصيرة ووسيطات سطر الأوامر.

$ python main.py -m hello -f thisfile.txt
[('-m', 'hello'), ('-f', 'thisfile.txt')]
[]

بعد تشغيل main.py ، يمكننا رؤية “thisfile.txt” في دليل العمل الخاص بنا. يحتوي على السلسلة “hello” المحولة إلى أحرف كبيرة (“HELLO”).

$ ls
main.py  thisfile.txt
$ cat thisfile.txt
HELLO

كيفية تحليل وسيطات سطر الأوامر باستخدام Argparse

توفر الوحدة النمطية argparse ، المضمنة أيضًا في مكتبة Python القياسية ، وظائف لتحليل وسيطات سطر الأوامر وكذلك إنشاء واجهات لسطر الأوامر.

  أفضل 9 بائعي SD-WAN للاختيار من بينها في عام 2022

لتحليل وسيطات سطر الأوامر ، دعنا نستورد فئة ArgumentParser من الوحدة النمطية argparse. هنا ، قمنا بإنشاء مثيل arg_parser ، وهو كائن ArgumentParser:

from argparse import ArgumentParser

arg_parser = ArgumentParser()

بعد ذلك ، نود إضافة وسيطتين لسطر الأوامر:

  • message: سلسلة الرسالة ، و
  • file: اسم الملف الذي نرغب في العمل معه.

الآن نسمي طريقة add_argument () على arg_parser لإضافة كلتا الوسيطتين. في استدعاء الأسلوب add_argument () ، يمكنك تعيين تعليمات لسلسلة (وصف للوسيطة).

arg_parser.add_argument('message',help='message string')
arg_parser.add_argument('file',help='filename')

حتى الآن ، أنشأنا arg_parser وأضفنا وسيطات سطر الأوامر. عند تشغيل البرنامج في سطر الأوامر ، يمكنك استخدام طريقة parse_args () في arg_parser للحصول على قيم الوسائط.

هنا ، نلتقط مساحة اسم الوسيطة في المتغير args. لذا يمكنك استخدام args.argument_name للحصول على قيم الوسائط.

بعد الحصول على قيم الوسائط ، نكتب سلسلة الرسالة مع تبديل الحالة (باستخدام طريقة السلسلة swapcase ()) إلى الملف.

args = arg_parser.parse_args()

message = args.message
file = args.file

with open(file,'w') as f:
     f.write(message.swapcase())

بتجميعها جميعًا ، إليك ملف main.py:

# main.py

from argparse import ArgumentParser

arg_parser = ArgumentParser()
arg_parser.add_argument('message',help='message string')
arg_parser.add_argument('file',help='filename')

args = arg_parser.parse_args()
print(args)

message = args.message
file = args.file

with open(file,'w') as f:
     f.write(message.swapcase())

فهم استخدام وسيطة سطر الأوامر

لفهم استخدام الوسائط عند تشغيل main.py ، يمكنك استخدام الخيار –help long كما هو موضح:

$ python3 main.py --help
usage: main.py [-h] message file

positional arguments:
  message     message string
  file        filename

optional arguments:
  -h, --help  show this help message and exit

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

$ python3 main.py -h
usage: main.py [-h] message file

positional arguments:
  message     message string
  file        filename

optional arguments:
  -h, --help  show this help message and exit

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

هنا ، مررنا وسيطة موضعية (مرحبًا) لسلسلة الرسالة ، لكننا لم نقدم أي قيمة لوسيطة الملف.

وقد حصلنا على خطأ يفيد بأن وسيطة الملف مطلوبة.

$ python3 main.py Hello
usage: main.py [-h] message file
main.py: error: the following arguments are required: file

عندما نقوم بتشغيل main.py مع كل من الوسيطات الموضعية ، نرى أن مجالات مساحة الاسم تحتوي على قيم الوسائط.

$ python3 main.py Hello file1.txt
# Output
Namespace(file="file1.txt", message="Hello")

الآن إذا فحصنا محتويات دليل العمل الحالي ، فسنجد أن البرنامج النصي ينشئ الملف file1.txt:

$ ls
file1.txt  main.py

سلسلة الرسالة الأصلية هي “Hello” ؛ بعد تبديل الحالة ، تكون سلسلة الرسالة في الملف “file1.txt” هي “hELLO”.

$ cat file1.txt
hELLO

كيفية جعل وسيطات سطر الأوامر اختيارية

لجعل وسيطات سطر الأوامر هذه اختيارية ، يمكنك أن تسبق اسم الوسيطة بـ -.

  أفضل 6 منصات لتوظيف مشغلي إدخال البيانات لحسابهم الخاص

دعنا نعدل main.py لجعل كل من وسائط الرسالة والملف اختيارية.

# main.py

from argparse import ArgumentParser

arg_parser = ArgumentParser()
arg_parser.add_argument('--message',help='message string')
arg_parser.add_argument('--file',help='filename')

نظرًا لأن وسيطات سطر الأوامر اختيارية ، يمكننا تعيين القيم الافتراضية لهذه الوسائط.

if args.message and args.file:
    message = args.message
    file = args.file
else:
    message="Python3"
    file="myfile.txt"

في هذه المرحلة ، يحتوي ملف main.py على الكود التالي:

# main.py

from argparse import ArgumentParser

arg_parser = ArgumentParser()
arg_parser.add_argument('--message',help='message string')
arg_parser.add_argument('--file',help='filename')

args = arg_parser.parse_args()
print(args)

if args.message and args.file:
    message = args.message
    file = args.file
else:
    message="Python3"
    file="myfile.txt"

with open(file,'w') as f:
     f.write(message.swapcase())

إذا تحققنا من الاستخدام ، فسنرى أن كلاً من الرسالة والملف وسيطات اختيارية. بمعنى أنه يمكنك الآن تشغيل main.py بدون هاتين الوسيطتين.

$ python3 main.py --help
usage: main.py [-h] [--message MESSAGE] [--file FILE]

optional arguments:
  -h, --help         show this help message and exit
  --message MESSAGE  message string
  --file FILE        filename
$ python3 main.py

في مساحة اسم الوسيطة ، يكون كل من الملف والرسالة بلا.

# Output
Namespace(file=None, message=None)

نرى أنه يتم استخدام اسم الملف الافتراضي والرسالة “myfile.txt” و “Python3”. الملف “myfile.txt” موجود الآن في دليل العمل:

$ ls
file1.txt  main.py  myfile.txt

ويحتوي على السلسلة النصية ‘Python3’ مع حالة الأحرف المتبادلة:

$ cat myfile.txt
pYTHON3

يمكنك أيضًا استخدام كل من الوسيطات –الرسالة و –الملف لجعل الأمر أكثر قابلية للقراءة.

$ python3 main.py --message Coding --file file2.txt
# Output
Namespace(file="file2.txt", message="Coding")

نرى الملف file2.txt في دليل العمل:

$ ls
file1.txt  file2.txt  main.py  myfile.txt

ويحتوي على السلسلة النصية “cODING” كما هو متوقع.

$ cat file2.txt
cODING

خاتمة

فيما يلي ملخص لما تعلمناه في هذا البرنامج التعليمي:

  • على غرار لغة البرمجة C ، في Python ، يمكنك الوصول إلى وسيطات سطر الأوامر من خلال تكرار متجه الوسيطة sys.argv. sys.argv[0] هو اسم نص بايثون. لذلك نحن مهتمون بتحليل الحجج sys.argv[1:].
  • ومع ذلك ، لتحسين إمكانية القراءة ولتتمكن من إضافة خيارات ، يمكنك استخدام وحدتي getopt و argparse.
  • يمكنك استخدام الوحدة النمطية getopt لتحليل قائمة وسيطات سطر الأوامر بدءًا من الفهرس 1 حتى نهاية القائمة. يمكنك تحديد كل من الخيارات القصيرة والخيارات الطويلة.
  • عندما يأخذ الخيار وسيطة ، يمكنك تحديد نقطتين (:) و = بعد الخيار القصير والخيار الطويل ، على التوالي.
  • باستخدام الوحدة النمطية argparse في Python ، يمكنك إنشاء مثيل لكائن ArgumentParser واستخدام طريقة add_argument () لإضافة وسيطة موضعية مطلوبة. استخدم – قبل اسم الوسيطة لجعلها اختيارية.
  • لاسترداد قيم وسيطات سطر الأوامر ، قم باستدعاء الأسلوب parse_args () على كائن ArgumentParser.

بعد ذلك ، تعرف على كيفية إجراء التجزئة الآمنة في Python.