PythonGuide/External Programs

من PFWiki

اذهب إلى: تصفح, البحث

التعامل مع تطبيقات اخرى

للآن تستطيع كتابة سكربتات جميلة بالبايثون ولكن ايضا قد نحتاج لإدخال بعض البيانات لبرنامج معين من خلال سطر الأوامر


sys.argv هى list تشمل كل المعاملات اللتى تم ارسالها لبرنامجك

  1. 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 (لاتهتم الآن) )

أدوات شخصية