للآن تستطيع كتابة سكربتات جميلة بالبايثون ولكن ايضا قد نحتاج لإدخال بعض البيانات لبرنامج معين من خلال سطر الأوامر
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)
Gimme usageتطبيق جيد ايضا ان تضع دالة بإسم usage توضح كيفية استخدام البرنامج
قم دائما بإختبار عدد المعاملات اللتى تم ارسالها للسكربت فأى عدد غير مقبول قم بعرض ال usage
def usage():
"""My fancy usage helper"""
........
def consoleMain():
if len(argv) != DEFINED_LENGTH:
GIMME_USAGE
if __name__=="__main__":
consoleMain()
Forget about usage GIMME optparserبايثون كالعادة توفر لك العديد والعديد لمساعدتك فتوفر لك اكثر من وحدة لمعالجة معاملات سطر الأوامر لاحظ الإستخدام التالى
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
os.systemلتنفيذ اوامر خاصة بالنظام توجد الدالة 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 (لاتهتم الآن) )