ยูทิลิตี Python

ในส่วนนี้ เราจะมาดูโมดูลยูทิลิตีมาตรฐานต่างๆ ของ Python บางส่วนเพื่อแก้ปัญหาทั่วไป

ระบบไฟล์ -- os, os.path, closureil

โมดูล *os* และ *os.path* มีฟังก์ชันมากมายสำหรับโต้ตอบกับระบบไฟล์ โมดูล *shutil* สามารถคัดลอกไฟล์ได้

  • เอกสารโมดูล OS
  • ชื่อไฟล์ = os.listdir(dir) -- รายการชื่อไฟล์ในเส้นทางไดเรกทอรีนั้น (ไม่รวม . และ ..) ชื่อไฟล์เป็นเพียงชื่อในไดเรกทอรีไม่ใช่เส้นทางสัมบูรณ์
  • os.path.join(dir, filename) -- เมื่อตั้งชื่อไฟล์จากรายการด้านบนแล้ว ใช้ในการตั้งชื่อไดเรกทอรีและชื่อไฟล์เข้าด้วยกันเพื่อสร้างเส้นทาง
  • os.path.abspath(path) -- หากระบุเส้นทาง จะแสดงรูปแบบสัมบูรณ์ เช่น /home/nick/foo/bar.html
  • os.path.dirname(path), os.path.basename(path) -- ระบุ dir/foo/bar.html แสดง ชื่อไดเรกทอรี "dir/foo" และ basename "bar.html"
  • os.path.exists(path) -- เป็นจริงหากมี
  • os.mkdir(dir_path) -- สร้าง 1 ไดเรกทอรี os.makedirs(dir_path) จะสร้างไดเรกทอรีที่จำเป็นทั้งหมดในเส้นทางนี้
  • offil.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

การสำรวจโมดูลทำงานได้ดีกับฟังก์ชัน Python help() และ dir() ในตัว ในล่าม ให้ใช้คำสั่ง "import os" แล้วใช้คำสั่งเหล่านี้เพื่อดูว่ามีอะไรบ้างที่อยู่ในโมดูล dir(os), help(os.listdir), dir(os.path), help(os.path.dirname)

การเรียกใช้กระบวนการภายนอก -- กระบวนการย่อย

โมดูล *subProcess* เป็นวิธีง่ายๆ ในการเรียกใช้คำสั่งภายนอกและบันทึกเอาต์พุต

  • เอกสารของโมดูลย่อย
  • เอาต์พุต = subprocess.check_output(cmd, stderr=subprocess.STDOUT) -- เรียกใช้คำสั่ง รอให้คำสั่งจบการทำงาน และส่งข้อความเอาต์พุตกลับมา คำสั่งจะทำงานโดยมีเอาต์พุตมาตรฐานและข้อผิดพลาดมาตรฐานรวมอยู่ในข้อความเอาต์พุตเดียว หากล้มเหลว จะมีการแสดง CalledProcessError
  • หากต้องการควบคุมการทำงานของกระบวนการย่อยมากขึ้น โปรดดูคลาสsubprocess.popen
  • นอกจากนี้ยังมี subProcess.call(cmd) ง่ายๆ ซึ่งเรียกใช้คำสั่งและดัมพ์เอาต์พุตไปยังเอาต์พุตของคุณและส่งรหัสข้อผิดพลาดกลับมา ซึ่งจะใช้ได้หากคุณต้องการเรียกใช้คำสั่ง แต่ไม่จำเป็นต้องบันทึกเอาต์พุตในโครงสร้างข้อมูล Python
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

ส่วน "ลอง:" จะมีโค้ดที่อาจทำให้ข้อยกเว้น ส่วน "ยกเว้น": จะเก็บโค้ดเพื่อเรียกใช้หากมีข้อยกเว้น หากไม่มีข้อยกเว้น ระบบจะข้ามส่วน ยกเว้น: (กล่าวคือ โค้ดนี้มีไว้สำหรับจัดการข้อผิดพลาดเท่านั้น ไม่ใช่กรณี "ปกติ" สำหรับโค้ด) คุณสามารถดูตัวชี้ไปยังออบเจ็กต์ข้อยกเว้นได้ด้วยไวยากรณ์ "ยกเว้น 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 ที่อาจมีเต็มหรือไม่ครบถ้วน และ baseurl ของหน้าเว็บที่มาจาก 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)

การออกกำลังกาย

หากต้องการฝึกใช้ระบบไฟล์และเนื้อหาคำสั่งภายนอก ให้ดูคัดลอกแบบฝึกหัดพิเศษ หากต้องการฝึกฝนเนื้อหา urllib โปรดดูแบบฝึกหัดปริศนาบันทึก