Python 유틸리티

이 섹션에서는 일반적인 문제를 해결하기 위해 Python의 여러 표준 유틸리티 모듈 중 몇 가지를 살펴봅니다.

파일 시스템 -- os, os.path, Shutil

*os* 및 *os.path* 모듈에는 파일 시스템과 상호작용하는 여러 함수가 포함되어 있습니다. *shutil* 모듈은 파일을 복사할 수 있습니다.

  • OS 모듈 문서
  • filenames = os.listdir(dir) -- 해당 디렉터리 경로의 파일 이름 목록입니다( . 및 ..). 파일 이름은 절대 경로가 아닌 디렉터리에 있는 이름일 뿐입니다.
  • os.path.join(dir, filename) -- 위 목록의 파일 이름이 지정된 경우 이를 사용하여 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' 및 기본 이름 'bar.html' 반환
  • os.path.exists(path) -- 존재하는 경우 true
  • os.mkdir(dir_path) -- dir을 하나 만들고 os.makedirs(dir_path)는 이 경로에 필요한 모든 dir을 만듭니다.
  • exitil.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* 모듈은 외부 명령어를 실행하고 그 출력을 캡처하는 간단한 방법입니다.

  • 하위 프로세스 모듈 문서
  • output = 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/전문가' 구조를 추가하여 다음과 같이 예외를 처리할 수 있습니다.

  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

try: 섹션에는 예외를 발생시킬 수 있는 코드가 포함되어 있습니다. 예외: 섹션에는 예외가 있을 때 실행할 코드가 있습니다. 예외가 없으면 예외: 섹션을 건너뜁니다 (즉, 해당 코드는 오류 처리 전용이며 코드의 '일반' 사례가 아님). 'IOError as e: ..' (e: 예외 객체를 가리킴) 문법을 사용하여 예외 객체 자체의 포인터를 가져올 수 있습니다.

HTTP -- urllib 및 urlparse

*urllib.request* 모듈은 URL 가져오기를 제공하며, URL을 읽을 수 있는 파일처럼 만듭니다. *urlparse* 모듈은 URL을 분해하여 구성할 수 있습니다.

  • urllib.request 모듈 문서
  • ufile = urllib.request.urlopen(url) -- 해당 URL에 대해 object와 같은 파일을 반환합니다.
  • text = ufile.read() -- 파일처럼 읽을 수 있습니다 (readlines() 등도 작동함).
  • info = ufile.info() -- 해당 요청의 메타 정보입니다. info.gettype()은 MIME 유형(예: 'text/html')입니다.
  • baseurl = ufile.geturl() -- 요청의 'base' URL을 가져오며, 리디렉션으로 인해 원본 URL과 다를 수 있습니다.
  • urllib.request.urlretrieve(url, filename) -- URL 데이터를 지정된 파일 경로로 다운로드
  • urllib.parse.urljoin(baseurl, url) -- 꽉 찼거나 가득 차지 않을 수 있는 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 작업이 실패할 경우 오류 메시지를 출력하기 위해 try/exception 로직을 추가하는 함수 버전입니다.

urlopen()이 중단된 것으로 보이면 시스템에서 일부 http 주소에 대한 직접 액세스를 허용하지 않을 수 있습니다. wget 또는 curl를 사용하여 동일한 URL을 가져와 이를 확인할 수 있습니다. 이러한 프로그램도 실패하면 프록시 서비스를 통해 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 자료를 연습하려면 로그 퍼즐 연습을 참조하세요.