PythonGuide/External Programs
من PFWiki
التعامل مع تطبيقات اخرى
للآن تستطيع كتابة سكربتات جميلة بالبايثون ولكن ايضا قد نحتاج لإدخال بعض البيانات لبرنامج معين من خلال سطر الأوامر
sys.argv هى list تشمل كل المعاملات اللتى تم ارسالها لبرنامجك
- echo .py
from sys import argv print "ARGV: ", argv for i, arg in enumerate(argv): print "Argv[%d]: %s"%(i, arg)
لاحظ ان اول معامل فى ال argv سيكون دائما هو اسم البرنامج
يتم الفصل بين كل معامل بإستخدام مسافة
لدمج اكثر من معامل ضعهم بين علامتى تنصيص
striky@striky-desktop:~/workspace/pytut/src$ python echo.py Hello ARGV: ['echo.py', 'Hello'] Argv[0]: echo.py Argv[1]: Hello striky@striky-desktop:~/workspace/pytut/src$ python echo.py "Hello World" ARGV: ['echo.py', 'Hello World'] Argv[0]: echo.py Argv[1]: Hello World
ماذا عن enumerate ؟
هى طريقة تقوم بإعادة index (لعدد الدورات) وقيمة من container (مثلا list ك argv)
[b]Gimme usage[/b]
تطبيق جيد ايضا ان تضع دالة بإسم usage توضح كيفية استخدام البرنامج قم دائما بإختبار عدد المعاملات اللتى تم ارسالها للسكربت فأى عدد غير مقبول قم بعرض ال usage
def usage(): """My fancy usage helper""" ........ def consoleMain(): if len(argv) != DEFINED_LENGTH: GIMME_USAGE if __name__=="__main__": consoleMain()
[b] Forget about usage GIMME optparser[/b]
بايثون كالعادة توفر لك العديد والعديد لمساعدتك فتوفر لك اكثر من وحدة لمعالجة معاملات سطر الأوامر لاحظ الإستخدام التالى
striky@striky-desktop:~$ python mufhrs.py -f http://linuxac.org/forum/forumdisplay.php?f=23 -l 1 -u 3 -s 1 -t vb > pgfihrsx2.txt
ياإلهى كيف تدير كل هذه المعاملات الغير معقولة ؟ انتبه جيدا لأن هذا هو جزء من حل السكربت المطلوب منك سابقا
هنا مثلا لفهرسة قسم فى منتدى نريد اقل ترتيب للصفحة واكثر ترتيب ومقدار الزيادة (ستفيدك كثيرا اذا قررت محاولة فهرسة منتدى SMF) ونوع المنتدى نخبر السكربت بهذا عن طريق تحديد اسم للمعامل وقيمة له مثلا -s لمقدر الزيادة وتكون قيمتها هى المعامل التالى لها1
-u عدد الصفحة المطلوب الإنتهاء عندها وقيمتها 3 -t لنوع المنتدى وقيمته vb وهكذا ، او ربما استخدام الصيغة المطولة --step=1 --upper=3 --ftype=vb لاحظ ان الترتيب ليس هاما!! اكيد اخذ العديد من الشروط والإختبارات (شكرا لبايثون والوحدةoptparse لقد اخذت الكثير من الجهد عن عاتقنا) هذا الجزء من حل السكربت المطلوب
def consoleMain(): optsparser=OptionParser() optsparser.add_option("-f", "--forum", dest="forumlink", help="Forum Section") optsparser.add_option("-l", "--lower", dest="lower", help="Lowest page") optsparser.add_option("-u", "--upper", dest="upper", help="Upper page") optsparser.add_option("-s", "--step", dest="step", help="Step") optsparser.add_option("-t", "--type", dest="ftype", help="Forum type (e.g) vb") options, args=optsparser.parse_args() #defaulted to sys.argv[1:] #print options, "====",args forumlink=optsparser.values.forumlink lower=int(optsparser.values.lower) upper=int(optsparser.values.upper) forumtype=optsparser.values.ftype.lower() step=int(optsparser.values.step)
1- يجب استدعاء ال الوحدة optparse او الصف OptionParser للإختصار
from optparse import OptionParser
2- انشاء كائن من OptionParser
optsparser=OptionParser()
3- اضافة اسماء المعاملات بإستخدام الطريقة add_option واللتى تأخذ معاملات عديده اهمها
1- الصورة المختصرة لإسم الإختيار -f
2- الصورة الطويلة (الكاملة) لإسم الإختيار -forum
3- اسم من اختيارك للحصول على قيمته وليكن forumlink مثلا
4- قسم المساعدة الخاص بالoption
optsparser.add_option("-f", "--forum", dest="forumlink", help="Forum Section") optsparser.add_option("-l", "--lower", dest="lower", help="Lowest page") optsparser.add_option("-u", "--upper", dest="upper", help="Upper page") optsparser.add_option("-s", "--step", dest="step", help="Step") optsparser.add_option("-t", "--type", dest="ftype", help="Forum type (e.g) vb")
عند استدعاءك للبرنامج فى وضع المساعدة help يتم تنفيذ شئ مشابه للتالى
Options: -h, --help show this help message and exit -f FORUMLINK, --forum=FORUMLINK Forum Section -l LOWER, --lower=LOWER Lowest page -u UPPER, --upper=UPPER Upper page -s STEP, --step=STEP Step -t FTYPE, --type=FTYPE Forum type (e.g) vb
striky@striky-desktop:~/workspace/pytut/src$ python mufhrs.py --help Usage: mufhrs.py [options] Options: -h, --help show this help message and exit -f FORUMLINK, --forum=FORUMLINK Forum Section -l LOWER, --lower=LOWER Lowest page -u UPPER, --upper=UPPER Upper page -s STEP, --step=STEP Step -t FTYPE, --type=FTYPE Forum type (e.g) vb
رائعة اليس كذلك ؟ للحصول على قيم الإختيارات
forumlink=optsparser.values.forumlink lower=int(optsparser.values.lower) upper=int(optsparser.values.upper) forumtype=optsparser.values.ftype.lower() step=int(optsparser.values.step)
ماهذا ؟ كيف عرفت حعلت بايثون اسماء الإختيارات كمتغيرات خاصة بالكائن ؟ ج: بعض سحر setattr :)
- قم بكتابة اداة مشابهة ل cat بإستخدام بايثون علما بأن ال stdin, stdout, stderr ستجدهم فى الوحدة sys
[b]os.system[/b] لتنفيذ اوامر خاصة بالنظام توجد الدالة system فى الوحدة os والتى تعيد ايضا ال exit status (اللتى يعيدها البرنامج عند انتهاءه لتشير لنجاح او حدوث خطأ اثناء التنفيذ) على فرض لدينا هذا السكربت exitstatus.py
#!/usr/bin/env python #-*- coding:utf-8 -*- def who(): name=raw_input("Name: ") if name != "Ahmed": print "Not Ahmed" exit(1) else: print "Welcome" who()
وقمنا بتنفيذ
striky@striky-desktop:~/workspace/pytut/src$ python exitstatus.py Name: Ahmed Welcome striky@striky-desktop:~/workspace/pytut/src$ echo $? 0
المتغير $? يشمل ال exit code الخاص بالبرنامج
-- استخدم دائما ال Exceptions
كثير من الأحيان نحتاج لتنفيذ اوامر والحصول على الخرج الخاص بها فى هذا المثال سنقوم بتنفيذ الأمر cat على الملف السابق ونقوم بقراءته داخل السكربت قم بإستدعاء الوحدة subprocess الخاصة بتنفيذ برامج فرعية داخل البرنامج (كبديل ل system و مشابهها)
>>> import subprocess as sb >>> ret=sb.call(['cat', 'exitstatus.py']) #!/usr/bin/env python #-*- coding:utf-8 -*- def who(): name=raw_input("Name: ") if name != "Ahmed": print "Not Ahmed" exit(1) else: print "Welcome" who() >>> ret 0
الطريقة call تقوم بتنفيذ ارم ما فى list حيث اول عنصر هو الأمر والباقى هو المعاملات اللتى يأخذها البرنامج
>>> catoutput=sb.Popen(["cat", "exitstatus.py"], stdout=sb.PIPE).communicate()[0] >>> print catoutput #!/usr/bin/env python #-*- coding:utf-8 -*- def who(): name=raw_input("Name: ") if name != "Ahmed": print "Not Ahmed" exit(1) else: print "Welcome" who()
نبدأ من اليمين لليسار الطريقة communicate تعيد لنا tuple تشمل الخرج والخطأ فنأخذ العنصر الأول وهو الخرج (ناتج تنفيذ العملية) Popen هو صف يأخذ اول عنصر args الأمر والمعاملات stdout, stdin, stderr هى الخرج والإدخال والخطأ الخاصين بالعملية ويأخذو قيم None او PIPE (قيمة خاصة لتعلم بوجوب فتح انبوبة pipe) او file object او رقم ليعبر عن file descriptor موجود shell قيمة منطقية ( True لتعبر عن تنفيذ البرنامج من خلال الشيل او False ليتم التنفيذ من خلال excevp (لاتهتم الآن) )
