ยูทิลิตี Python

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

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

โมดูล *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, แสดงผล dirname "dir/foo" และ basename "bar.html"
  • os.path.exists(path) -- จริง หากมี
  • os.mkdir(dir_path) -- ทำให้ dir 1, os.makedirs(dir_path) สร้าง dir ที่จำเป็นทั้งหมดในเส้นทางนี้
  • 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() ในตัว ในล่าม ให้ "นำเข้าระบบปฏิบัติการ" แล้วใช้คำสั่งต่อไปนี้เพื่อดูสิ่งที่มีอยู่ในโมดูล 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.. ซึ่งคุณอาจเคยเห็นมาแล้ว 2-3 ครั้ง) หรือข้อผิดพลาดเกี่ยวกับการเปิดไฟล์เนื่องจากไม่มีไฟล์อยู่ (IOError) ดูข้อมูลเพิ่มเติมในบทแนะนำข้อยกเว้น และดูรายการข้อยกเว้นทั้งหมด

ถ้าไม่มีรหัสการจัดการข้อผิดพลาด (ดังที่เราได้ดำเนินการไปแล้ว) ข้อยกเว้นรันไทม์จะทำให้โปรแกรมหยุดทำงานพร้อมกับข้อความแสดงข้อผิดพลาด ซึ่งเป็นลักษณะการทำงานเริ่มต้นที่ดีและคุณเคยเห็นมาหลายครั้งแล้ว คุณสามารถเพิ่ม "ลอง/ยกเว้น" ให้กับโค้ดของคุณเพื่อจัดการกับข้อยกเว้น ดังนี้

  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() -- รับ "base" URL ของคำขอ ซึ่งอาจแตกต่างจาก URL เดิมเนื่องจากการเปลี่ยนเส้นทาง
  • urllib.request.urlretrieve(url, ชื่อไฟล์) -- ดาวน์โหลดข้อมูล URL ไปยังเส้นทางของไฟล์ที่ระบุ
  • urllib.parse.urljoin(baseurl, url) -- กำหนด URL ที่อาจเต็มหรือไม่เต็มได้ และ baseurl ของหน้าเว็บที่เป็นต้นทาง ให้แสดง 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 ผ่านพร็อกซี service. บทแนะนำนี้ไม่ครอบคลุมถึงการกำหนดค่าการเข้าถึงพร็อกซี

## 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 โปรดดูที่Log Puzzle Exercise