Author Topic: Talking to others التعامل مع تطبيقات اخرى  (Read 818 times)

Ahmed Youssef

  • Helping Freak
  • Administrator
  • Active Member
  • *****
  • Posts: 242
    • View Profile
    • WWW
    • Email
Talking to others التعامل مع تطبيقات اخرى
« on: December 23, 2008, 12:46:16 AM »

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


sys.argv هى list تشمل كل المعاملات اللتى تم ارسالها لبرنامجك
#echo .py
Code: [Select]
from sys import argv 

print "ARGV: ", argv

for i, arg in enumerate(argv):
print "Argv[%d]: %s"%(i, arg)


لاحظ ان اول معامل فى ال argv سيكون دائما هو اسم البرنامج
يتم الفصل بين كل معامل بإستخدام مسافة
لدمج اكثر من معامل ضعهم بين علامتى تنصيص
Code: [Select]
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
Code: [Select]
def usage(): 
"""My fancy usage helper"""
........


def consoleMain():
if len(argv) != DEFINED_LENGTH:
GIMME_USAGE

if __name__=="__main__":
consoleMain()


Forget about usage GIMME optparser


بايثون كالعادة توفر لك العديد والعديد لمساعدتك فتوفر لك اكثر من وحدة لمعالجة معاملات سطر الأوامر لاحظ الإستخدام التالى
Code: [Select]
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 لقد اخذت الكثير من الجهد عن عاتقنا)
هذا الجزء من حل السكربت المطلوب
Code: [Select]
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 للإختصار
Code: [Select]
from optparse import OptionParser

2- انشاء كائن من OptionParser
Code: [Select]
    optsparser=OptionParser()


3- اضافة اسماء المعاملات بإستخدام الطريقة add_option واللتى تأخذ معاملات عديده اهمها
1- الصورة المختصرة لإسم الإختيار   -f
2- الصورة الطويلة (الكاملة) لإسم الإختيار  -forum
3- اسم من اختيارك للحصول على قيمته وليكن forumlink مثلا
4- قسم المساعدة الخاص بالoption

Code: [Select]
    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 يتم تنفيذ شئ مشابه للتالى
Code: [Select]
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

Code: [Select]
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

رائعة اليس كذلك ؟
للحصول على قيم الإختيارات
Code: [Select]
    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
Code: [Select]
#!/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()

وقمنا بتنفيذ
Code: [Select]
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 و مشابهها)
Code: [Select]
>>> 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 حيث اول عنصر هو الأمر والباقى هو المعاملات اللتى يأخذها البرنامج
Code: [Select]
>>> 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 (لاتهتم الآن) )


« Last Edit: September 08, 2009, 08:22:43 PM by Ahmed Youssef »
Logged

Life is just a chance to grow a soul. - A. Powell
Weblog: http://ahmedyoussef.wordpress.com/