برامج بايثون المساعدة

في هذا القسم، نلقي نظرة على بعض وحدات الأدوات القياسية المتعددة في بايثون لحل المشكلات الشائعة.

نظام الملفات -- os, os.path, sendil

تتضمّن وحدتَي *os* و *os.path* العديد من الدوال للتفاعل مع نظام الملفات. يمكن لوحدة *shutil* نسخ الملفات.

  • مستندات وحدة نظام التشغيل
  • filenames = os.listdir(dir) -- قائمة أسماء الملفات في مسار الدليل هذا (لا يشمل . و ..). أسماء الملفات هي فقط الأسماء الواردة في الدليل، وليست مساراتها المطلقة.
  • os.path.join(dir, filename) -- عند تحديد اسم ملف من القائمة أعلاه، استخدِم هذا لتجميع dir واسم الملف معًا لإنشاء مسار
  • os.path.abspath(path) -- تحديد مسار، ارجع إلى شكل مطلق، على سبيل المثال: /home/nick/foo/bar.html
  • os.path.dirname(path) وos.path.basename(path) -- عند استعراض dir/foo/bar.html، يمكنك عرض اسم المسار "dir/foo" واسم الأساسي "bar.html"
  • os.path.exists(path) -- صحيح إذا كان موجودًا
  • os.mkdir(dir_path) -- ينشئ dir واحدًا، يصنع os.makedirs(dir_path) جميع التوجيه المطلوبة في هذا المسار
  • install.copy(source-path, dest-path) -- نسخ ملف (من المفترض أن تتوفّر أدلة مسارات الوجهة)
## Example pulls filenames from a dir, prints their relative and absolute paths
def printdir(dir):
  filenames = os.listdir(dir)
  for filename in filenames:
    print(filename)  ## foo.txt
    print(os.path.join(dir, filename)) ## dir/foo.txt (relative to current dir)
    print(os.path.abspath(os.path.join(dir, filename))) ## /home/nick/dir/foo.txt

يعمل استكشاف وحدة ما بشكل جيد مع الدالتين help() وdir() المدمجة. في أداة الترجمة الفورية، نفِّذ عملية استيراد os، ثم استخدِم هذه الأوامر لإلقاء نظرة على ما هو متاح في الوحدة: dir(os) وhelp(os.listdir) وdir(os.path) وhelp(os.path.dirname).

تشغيل العمليات الخارجية -- العملية الفرعية

تعتبر وحدة *العملية الفرعية* طريقة بسيطة لتشغيل أمر خارجي وتسجيل مخرجاته.

  • مستندات وحدة العمليات الفرعية
  • المخرجات = subprocess.check_output(cmd, stderr=subprocess.STDOUT) -- لتشغيل الأمر وانتظار خروجه منه وإرجاع نص الإخراج الخاص به. يتم تشغيل الأمر مع دمج مخرجاته العادية والأخطاء العادية في نص إخراج واحد. وإذا فشلت، فإنها تعرض الخطأ CalledProcessError.
  • إذا كنت تريد مزيدًا من التحكّم في تشغيل العملية الفرعية، يُرجى الاطّلاع على فئة subprocess.popen
  • هناك أيضًا عملية subprocess.call(cmd) بسيطة تعمل على تشغيل الأمر وتفريغ مخرجاتها في الإخراج الخاص بك وإرجاع رمز الخطأ الخاص بها. ويعمل هذا إذا كنت تريد تشغيل الأمر ولكنك لا تحتاج إلى التقاط مخرجاته في هياكل بيانات بايثون.
import subprocess

## Given a dir path, run an external 'ls -l' on it --
## shows how to call an external program
def listdir(dir):
  cmd = 'ls -l ' + dir
  print("Command to run:", cmd)   ## good to debug cmd before actually running it
  (status, output) = subprocess.getstatusoutput(cmd)
  if status:    ## Error case, print the command's output to stderr and exit
    sys.stderr.write(output)
    sys.exit(status)
  print(output)  ## Otherwise do something with the command's output

الاستثناءات

يمثل الاستثناء خطأ في وقت التشغيل يوقف التنفيذ العادي في سطر معين وينقل عنصر التحكم إلى رمز معالجة الأخطاء. يوضح هذا القسم الاستخدامات الأساسية للاستثناءات. على سبيل المثال، قد يكون خطأ وقت التشغيل هو أن المتغير المستخدَم في البرنامج لا يحتوي على قيمة (ValueError .. ربما رأيت ذلك عدة مرات)، أو خطأ في عملية فتح الملف بسبب عدم وجود الملف (IOError). تعرف على المزيد في البرنامج التعليمي للاستثناءات وراجع قائمة الاستثناءات بالكامل.

بدون وجود أي رمز في معالجة الأخطاء (كما فعلنا حتى الآن)، يؤدي استثناء وقت التشغيل إلى إيقاف البرنامج وتظهر رسالة خطأ. هذا سلوك تلقائي جيد، وقد رأيته عدة مرات. يمكنك إضافة بنية "try/except" إلى التعليمة البرمجية للتعامل مع الاستثناءات، مثل ما يلي:

  try:
    ## Either of these two lines could throw an IOError, say
    ## if the file does not exist or the read() encounters a low level error.
    f = open(filename, 'rb')
    data = f.read()
    f.close()
  except IOError:
    ## Control jumps directly to here if any of the above lines throws IOError.
    sys.stderr.write('problem reading:' + filename)
  ## In any case, the code then continues with the line after the try/except

يتضمن قسم test: التعليمة البرمجية التي قد تنشئ استثناء. يحتوي القسم باستثناء: على التعليمة البرمجية للتشغيل في حالة وجود استثناء. إذا لم يكن هناك استثناء، يتم تخطّي القسم "باستثناء:" (أي أنّ الرمز مخصّص لمعالجة الأخطاء فقط، وليس الحالة "العادية" للرمز). يمكنك الحصول على مؤشر إلى كائن الاستثناء نفسه باستخدام البنية "باستثناء IOError على النحو e: .." (يشير الرمز e إلى كائن الاستثناء).

HTTP -- urllib وurlparse

توفر الوحدة *urllib.request* جلب عنوان URL، بحيث يشبه عنوان URL ملفًا يمكنك القراءة منه. يمكن لوحدة *urlparse* تفكيك وتجميع عناوين URL.

  • مستندات وحدة urllib.request
  • ufile = urllib.request.urlopen(url) -- يعرض ملفًا مثل كائن لعنوان URL هذا
  • text = ufile.read() -- يمكن القراءة منه، مثل أحد الملفات (readlines() وما إلى ذلك. يعمل أيضًا)
  • info = ufile.info() -- المعلومات الوصفية لهذا الطلب. info.gettype() هي نوع mime، على سبيل المثال 'text/html'
  • baseurl = ufile.geturl() -- تحصل على عنوان url "base" للطلب، والذي قد يختلف عن العنوان الأصلي بسبب عمليات إعادة التوجيه
  • urllib.request.urlretrieve(url, filename) -- يقوم بتنزيل بيانات عنوان URL إلى مسار الملف المحدد
  • urllib.parse.urljoin(baseurl, url) -- إذا كان عنوان URL قد يكون ممتلئًا أو لا يكون ممتلئًا، يعرض عنوان URL الأساسي للصفحة التي تأتي منها عنوان URL كاملاً. استخدِم الطريقة geturl() أعلاه لتوفير عنوان URL الأساسي.

توجد جميع الاستثناءات في urllib.error.

from urllib.request import urlopen

## Given a url, try to retrieve it. If it's text/html,
## print its base url and its text.
def wget(url):
  ufile = urlopen(url)  ## get file-like object for url
  info = ufile.info()   ## meta-info about the url content
  if info.get_content_type() == 'text/html':
    print('base url:' + ufile.geturl())
    text = ufile.read()  ## read all its text
    print(text)

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

إذا بدا أنّ الموقع الإلكتروني urlopen() معلق، قد لا يسمح النظام بالوصول المباشر إلى بعض عناوين http. يمكنك التحقق من ذلك من خلال محاولة جلب عنوان URL نفسه باستخدام wget أو curl. في حال إخفاق هذه البرامج أيضًا، ستحتاج إلى جلب محتوى http من خلال خدمة الخادم الوكيل. لا يتناول هذا البرنامج التعليمي ضبط الوصول إلى الخادم الوكيل.

## Version that uses try/except to print an error message if the
## urlopen() fails.
def wget2(url):
  try:
    ufile = urlopen(url)
    if ufile.info().get_content_type() == 'text/html':
      print(ufile.read())
  except IOError:
    print('problem reading url:', url)

التمارين الرياضية

للتدرب على نظام الملفات ومواد الأوامر الخارجية، راجع نسخ التمرين الخاص. للتدرب على مادة عنوان URL، راجع تمرين أحجية التسجيل.