파이썬 라이브러리 2

( 출처 : https://wikidocs.net/book/5445 )


목차

  1. datetime
  2. collections
  3. pprint
  4. random
  5. itertools
  6. functools
  7. os.path
  8. glob
  9. pickle
  10. argparse
  11. getpass
  12. 동시 실행
  13. json
  14. sys.argv
  15. abc
  16. pip
  17. requests
  18. 클로저 (closure)


7. os.path

import os
  • 경로명(파일명) 관련 함수


사용모듈 설명
os.listdir(path) path 하위의 파일&디렉터리 리스트로 리턴한다.
os.path.splitext(path) 파일명 & 확장자로 구분
os.path.isdir(path) directory 여부
os.path.isfile(path) file 여부


8. glob ( 파일 검색 )

import glob

# 현재 경로의 모든 txt 파일 반환
file_list=[]
for f in glob.glob("*.txt"):
	file_list.append(f)
	
# 현재 경로 & 하위 경로의 모든 txt 파일 반환
file_list=[]
for f in glob.glob("**/*.txt"):
	file_list.append(f)


9. pickle

import pickle


  • pickle 파일 저장하기
with open('data.p', 'wb') as f:
        pickle.dump(data, f)


  • pickle 파일 불러오기
with open("data.p", 'rb') as f:
        data = pickle.load(f)


10. argparse

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('-a', '--add', type=int, nargs='+', metavar='N', help='더할 숫자')
parser.add_argument('-m', '--mul', type=int, nargs='+', metavar='N', help='곱할 숫자')
  • -a & --add : 명령행 옵션
  • type : 인자로 받는 값의 데이터 형태 설정
  • nargs : 인자로 받을 값의 개수 ( + : 1개 이상 )


11. getpass

파일명: getpass_sample.py

import getpass

passwd = getpass.getpass("Password:")
  • 화면에 입력하는 비밀번호가 노출 X


12. 동시 실행

(1) Threading : thread 기반의 병렬 처리

ex) 페이지 리소스를 여러 thread를 사용하여 동시에 저장하도록!


(여러 thread에서 동시에 수행할) 함수 구현 : get_wikidocs

import urllib.request


def get_wikidocs(page):
    print("wikidocs page:{}".format(page))  
    resource = 'https://wikidocs.net/{}'.format(page)
    try:
        with urllib.request.urlopen(resource) as s:
            with open('wikidocs_%s.html' % page, 'wb') as f:
                f.write(s.read())
    except urllib.error.HTTPError:
        return 'Not Found'


과정

  • (1) 빈 thread 리스트 생성하기
  • (2) for loop을 돌면서
    • (2-1) threading.Thread로 thread 생성
      • target : 함수
      • args : 함수의 인자
    • (2-2) thread 시작 ( t.start() )
    • (2-3) thread 리스트에 해당 thread 추가
  • (3) for loop을 돌면서
    • thread들 join하기
pages = [12, 13, 14, 15, 17, 18, 20, 21, 22, 24]
threads = []
for page in pages:
    t = threading.Thread(target=get_wikidocs, args=(page, ))
    t.start()
    threads.append(t)

for t in threads:
    t.join()  


(2) Multiprocessing : 프로세스 기반의 병렬처리

  • Thread : CPU연산만 수행하는 경우에 수행시간에 전혀 이득이 없음

  • multiprocessing 모듈 : 멀티 프로세스와 별개의 메모리를 사용하여 완전히 독립적인 병렬 프로그래밍 가능

    ( 여러개의 CPU를 가지고 있는 멀티코어 환경에서만 )


multiprocessing.Process

import multiprocessing

procs = []

for i in range(4):
    p = multiprocessing.Process(target=heavy_work, args=(i, ))
    p.start()
    procs.append(p)

for p in procs:
    p.join()  


multiprocessing.Pool

import multiprocessing

pool = multiprocessing.Pool(processes=4)

pool.map(heavy_work, range(4))
pool.close()
pool.join()


(3) concurrent.futures : 병렬 작업

  • threading 모듈 : thread 구현
  • multiprocessing 모듈 : multi process 프로그램을 구현
  • concurrent.futures 모듈 :
    • 동일한 규칙으로 스레드 & 멀티 프로세스 코드를 쉽게 작성


def heavy_work(name):
    result = 0
    for i in range(4000000):
        result += i
    print('%s done' % name)
    return result
import concurrent.futures

total_result = 0

pool = concurrent.futures.ProcessPoolExecutor(max_workers=4)

procs = []
for i in range(4):
    procs.append(pool.submit(heavy_work, i))

for p in concurrent.futures.as_completed(procs):
    total_result += p.result()


(4) subprocess : 시스템 명령어 실행

subprocess 모듈 : 시스템 명령을 다양한 방법으로 실행하는 모듈


example 1: 현재 디렉토리의 파일 목록 실행하기 ( ls -l )

이 결과(output)을, file로 저장하려면?

import subprocess

with open('out.txt', 'wb') as f:
    out = subprocess.run(['ls', '-l'], capture_output=True) # 리눅스 
    #out = subprocess.run(['dir'], capture_output=True) # 윈도우
    f.write(out.stdout)


example 2 : 현재 디렉터리의 하위 디렉터리를 포함한 모든 html 파일에서 “python”이라는 문자열이 포함되어 있는 부분을 전부 찾아서 출력

  • use shell=True
import subprocess

subprocess.run('find ./ -name "*.html"|xargs grep "python"', shell=True)