Tiện ích Python

Trong phần này, chúng ta sẽ xem xét một số mô-đun tiện ích tiêu chuẩn của Python để giải quyết các vấn đề thường gặp.

Hệ thống tệp -- os, os.path, closeil

Các mô-đun *os* và *os.path* bao gồm nhiều hàm để tương tác với hệ thống tệp. Mô-đun *shutil* có thể sao chép tệp.

  • tài liệu về mô-đun hệ điều hành
  • tên tệp = os.listdir(dir) -- danh sách tên tệp trong đường dẫn thư mục đó (không bao gồm . và ..). Tên tệp chỉ là các tên trong thư mục, chứ không phải là đường dẫn tuyệt đối.
  • os.path.join(dir, filename) – với tên tệp từ danh sách trên, sử dụng tên này để tập hợp thư mục và tên tệp lại với nhau tạo thành một đường dẫn
  • os.path.abspath(path) -- cho sẵn một đường dẫn, trả về một dạng tuyệt đối, ví dụ: /home/nick/foo/bar.html
  • os.path.dirname(path), os.path.basename(path) -- cho trước dir/foo/bar.html, hãy trả về dirname "dir/foo" và tên cơ sở "bar.html"
  • os.path.exists(path) – true nếu có
  • os.mkdir(dir_path) -- tạo một dir, os.makedirs(dir_path) tạo tất cả tệp cần thiết trong đường dẫn này
  • imil.copy(source-path, dest-path) – sao chép một tệp (cần có thư mục đường dẫn đích)
## 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

Việc khám phá một mô-đun hoạt động tốt với các hàm python Help() và dir() tích hợp sẵn. Trong phiên dịch, hãy "nhập hệ điều hành", sau đó sử dụng các lệnh sau để xem nội dung có trong mô-đun: dir(os), Help(os.listdir), dir(os.path), Help(os.path.dirname).

Chạy quy trình bên ngoài – quy trình phụ

Mô-đun *subprocess* là một cách đơn giản để chạy một lệnh bên ngoài và thu thập dữ liệu đầu ra của lệnh đó.

  • tài liệu về mô-đun quy trình phụ
  • output = subprocess.check_output(cmd, stderr=subprocess.STDOUT) -- chạy lệnh, chờ nó thoát và trả về văn bản đầu ra của nó. Lệnh này được chạy với kết quả đầu ra chuẩn và sai số chuẩn vào một văn bản đầu ra. Nếu không thành công, hệ thống sẽ gửi một CallProcessError.
  • Nếu bạn muốn có nhiều quyền kiểm soát hơn đối với việc chạy quy trình phụ, hãy xem lớp quy trình phụ (subprocess.popen)
  • Ngoài ra còn có một subprocess.call(cmd) đơn giản chạy lệnh và kết xuất kết quả vào kết quả của bạn và trả về mã lỗi. Phương thức này hoạt động nếu bạn muốn chạy lệnh nhưng không cần thu thập dữ liệu đầu ra của lệnh vào cấu trúc dữ liệu 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

Ngoại lệ

Một ngoại lệ biểu thị lỗi thời gian chạy khiến quá trình thực thi bình thường trên một dòng cụ thể tạm dừng và chuyển quyền kiểm soát thành mã xử lý lỗi. Phần này chỉ giới thiệu các cách sử dụng ngoại lệ cơ bản nhất. Ví dụ: lỗi thời gian chạy có thể là biến được sử dụng trong chương trình không có giá trị (ValueError .. bạn có thể đã thấy lỗi này một vài lần) hoặc lỗi thao tác mở tệp do tệp không tồn tại (IOError). Tìm hiểu thêm trong hướng dẫn về các trường hợp ngoại lệ và xem toàn bộ danh sách ngoại lệ.

Khi không có mã xử lý lỗi nào (như chúng tôi đã làm từ trước đến nay), ngoại lệ trong thời gian chạy sẽ tạm dừng chương trình kèm theo thông báo lỗi. Đây là một hành vi mặc định tốt mà bạn đã thấy nhiều lần. Bạn có thể thêm lựa chọn "thử/ngoại trừ" cấu trúc vào mã của bạn để xử lý các ngoại lệ, chẳng hạn như:

  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

Phần try: bao gồm mã có thể gửi một ngoại lệ. Phần ngoại trừ: chứa mã để chạy nếu có ngoại lệ. Nếu không có ngoại lệ, ngoại trừ phần: bị bỏ qua (nghĩa là mã đó chỉ dùng để xử lý lỗi, không phải là trường hợp "bình thường" của mã). Bạn có thể nhận một con trỏ đến chính đối tượng ngoại lệ với cú pháp "ngoại trừ IOError dưới dạng e: .." (e trỏ đến đối tượng ngoại lệ).

HTTP -- urllib và urlparse

Mô-đun *urllib.request* cung cấp tính năng tìm nạp URL – làm cho url trông giống như một tệp mà bạn có thể đọc. Mô-đun *urlparse* có thể tách riêng và tập hợp các URL với nhau.

  • Tài liệu về mô-đun urllib.request
  • ufile = urllib.request.urlopen(url) – trả về một tệp giống như đối tượng cho url đó
  • text = ufile.read() -- có thể đọc từ tệp này, giống như một tệp (readlines(), v.v. cũng hoạt động)
  • info = ufile.info() -- thông tin meta cho yêu cầu đó. info.gettype() là loại mime, ví dụ: "text/html"
  • baseurl = ufile.geturl() -- nhận "base" url cho yêu cầu, có thể khác với URL ban đầu do các lệnh chuyển hướng
  • urllib.request.urlRequested(url, tên tệp) – tải dữ liệu url xuống đường dẫn tệp nhất định
  • urllib.parse.urljoin(baseurl, url) -- với một url có thể đầy hoặc có thể đầy và url base của trang mà nó đến, trả về một url đầy đủ. Sử dụng geturl() ở trên để cung cấp url cơ sở.

Tất cả các trường hợp ngoại lệ đều nằm trong 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)

Mã trên hoạt động tốt, nhưng không bao gồm cách xử lý lỗi nếu url không hoạt động vì lý do nào đó. Dưới đây là một phiên bản của hàm bổ sung logic thử/ngoại trừ để xuất thông báo lỗi nếu thao tác URL không thành công.

Nếu urlopen() có vẻ như đang bị treo, hệ thống của bạn có thể không cho phép truy cập trực tiếp vào một số địa chỉ http. Bạn có thể xác minh điều này bằng cách cố gắng tìm nạp cùng một URL bằng cách sử dụng wget hoặc curl Nếu những chương trình này cũng không thành công, bạn sẽ cần tìm nạp nội dung http qua proxy . Hướng dẫn này không đề cập đến việc định cấu hình truy cập proxy.

## 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)

Bài tập

Để thực hành tài liệu về hệ thống tệp và lệnh bên ngoài, hãy xem phần Sao chép bài tập đặc biệt. Để thực hành tài liệu urllib, hãy xem Bài tập đố vui về nhật ký.