2019년 7월 3일 수요일

[강좌]옛날강좌들-열혈강의 파이썬

 熱血講義 Python  


강좌 정보

  • 출판년도 : 2005-08-29
  • 파이썬 2.x 에 대한 강좌
  • 유트브 채널 : 링크

강사 정보

  • 이강성

기타 설정

VIM 파이썬 관련 설정


1장-요약

  • raw_input는 파이썬 3에서는 input으로 통합됨.
  • 파이썬 사용처 (2000 년대)
  • 시스템 관리(스크립팅)
  • GUI
  • 인터넷 프로그래밍
  • DB 프로그래밍
  • 각종 Text 프로세싱
  • 분산처리
  • 수치연산, 그래픽스
  • 파이썬 메뉴얼 (자주 사용됨)
  • 한글 설정
  • PYTHON_HOME\Lib\site.py
  • encoding=”utf-8”
  • 기타 환경 설정
  • 유니코드 코텍 설치
  • 파이썬 실행 환경 설정
  • PATH :
  • PYTHONPATH : 라이브러리(사용자)
  • PYTHONSTARTUP : 원도우 시작 프로그램과 비슷

2장-요약

  • 사용자정의 변수 이름이나 함수 이름 작성시 기존 모듈이나 함수명은 피하라 충돌이 발생한다.
  • 충돌시 del <변수명> 으로 초기화 할 수 있음.
  • 연속라인 \
  • 확장 치환문
  • x <연산자>= y 의미는 x = x <연산자> (y)와 같다.
  • 파이썬 식 실행
  • eval()
  • 문 수행 - exec()
  • print x, 이렇게 입력하면 줄바꿈을 방지 할 수있다. -> 2.x 에서만
  • <항목> in L : 리스트 L에 <항목> 존재 여부 확인
  • type(자료형)
  • type(b) == type(0) : 정수형 비교
  • type(b) == type(‘’) : 문자열형 여부 비교
  • [] - 리스트 , {} - 사전 , () - 튜플
  • types - 파이썬 정의 객체들
  • is - 객체의 신원 식별
  • 같은 객체를 참조하면 True, 아니면 False
  • == : 같은 값을 가지고 있는 참조

3장-요약

  • int 최대 크기
  • sys.maxint
  • 0b10 -> 이진수
  • 0x10 -> 16진수
  • 0o10 -> 8진수
  • 2 ** 3 ** 2
  • 2 ** (3 ** 2) 와 동일함
  • 5 // 3
  • 몫 연산자
  • 4 + 3.0
  • 결과 : 7.0
  • 두 수중 하나가 실수 이면 실수 결과
  • divmod(5,3) : 몫과 나머지 한 번에 계산하는 함.
  • 결과 : (1, 2)
  • 비트 단위 연산자
  • ~ : 보수
  • << , >> : 좌측 쉬프트, 우측시프트
  • & : 비트 and
  • | : 비트 or
  • ^ : 비트 xor (서로 다른 값일때 true)
  • 복소수.conjugate() : 컬레 복소수
  • 수치 연산 모듈들
  • math : 실수 연산
  • cmath : 복소수 연산

4장

  • escape 문자
  • \012  or \n : 줄바꿈
  • \0xx : 8진수 코드
  • \xXX : 16진수 코드
  • \e : Esc 키
  • 문자열 : 직접적인 변경은 불가
  • 포맷팅 (c언어와 비슷)
  • print ‘%s 님 -- ‘ %name
  • ‘%3d -- %5.2f -- %.2e’ %(10, 32.3, 101.3)
  • e - 지수형태
  • d - 숫자
  • f - 실수
  • o - 8진수, x - 16 진수(소) , X - 16진수(대)
  • 사전을 이용한 포매팅
  • print ‘%(이름)s -- %(전화번호)s’ %{‘이름’:’이창훈’, ‘전화번호’:1234}
  • vars() : 지역변수를 사전형태로 출력함.
  • 문자열 정렬 함수:
  • center() - 중앙 정렬
  • ljust() - 왼쪽 정렬
  • rjust() - 오른쪽 정렬
  • ** 문자열 결합시 s+=’문자열’은 성능 좋지 않다
  • 대체 방법은 문자열 List 변환 후 join을 사용하면 빠르다.
  • t = []
  • for k in range(10000):
       t.append(‘spam’)
    s = ‘’.join(t)
  • string 모듈
  • 모듈 상수
  • digits - 문자 문자열 0-9
  • octdigits -
  • hexdigits
  • letters
  • lowercase
  • uppdercase
  • punctuation
  • printable
  • whitespace
  • 모듈 함수
  • 대부분의 문자열 메쏘드와 동일
  • capwords(str) - 각 단어의 첫문자을 대문자로
  • zfill(str, n) - 왼쪽의 빈자로를 0으로 채운다.
  • __doc__ 문자열 만들기
  • 모듈 - 파일의 첫 문자열
  • 함수 - 함수의 첫 문자열
  • 클래스, 메써드 .. 등도 마찬가지임.
  • help() : 이용하여 볼수 있음.

5장

  • 리스트를 stack으로 사용하기
  • append(), pop()
  • 리스트를 queue로 사용하기
  • append(), pop(0)
  • cmp(a, b) 내장함수
  • 3.x는 존재하지 않는다.
  • 대신 (‘a’ < ‘b’) - (‘a’ > ‘b’) 할 수 있음.
  • 순한 참조 리스트
  • GNU = [‘is not Unix’]
  • GNU.insert(0, GNU)
  • >> [[...], 'is not Unix']
  • 잘못 사용하면 메모리 누수가 발생할 수 있으므로 약한 참조(참조 카운트를 포함되지)를 이용해야 한다.
  • range를 이용한 변수 초기화
  • sun,mon,tue,wed,thu,fri,sat = range(7)
  • dir() - 지역적으로 사용가능한 이름의 리스트 얻기
  • dir(sys) - 모듈, 클래스등의 이름 리스트 얻기
  • 명령행 인수 처리
  • sys.argv
  • 명령행 option 처리
  • getopt.getopt(인수리스트, 옵션문자열)
  • 반환 : 옵션리스트 , 나머지 인수리스트
  • 옵션문자열 : abc:d:
  • c: 옵션는 파라미터 있는 옵션을 의미한다. 즉 -c123 있는 형태
  • 1차원 배열 표현
  • [1,2,3,4]
  • range(10)
  • [0] * 10
  • [None] * 10
  • 2차원 배열 표현
  • [ [1,2,3], [4,5,6] , [7,8,9]]
  • 접근 [1][2] ==> 6
  • 리스트로 배열 표현할 때 주의할점
  • [[0] * 4] * 3
  • [0] * 4 의 1차원 배열 3개를 참조하는 변수만 생성된다. ** 주의
  • 위 해당하는 대체 방법은 올바른 방법 **
  • [[0] * 4 for x in range(3)]
  • array 모듈 이용하기
  • arr = array(‘i’, range(10))
  • 리스트와 유사한 메소드 제공
  • 표준 아닌 모듈 Numeric 를 사용하여 array 생성할 수도 있음.
  • 행렬 계산에 유용하다.

6장 - 튜플

  • 튜플 만들기
  • t = ()
  • t = (1, 2, 3)
  • t = 1, 2, 3
  • t = (1, )
  • t = 1,
  • 1개 요소를 가지 튜플을 정의할때도 ‘,’를 써야 한다.
  • 만약 쓰지 않는다면 일반 변수가 된다.
  • 튜플 연산
  • 인텍싱, 슬라이싱, 반복, 연결, 길이, 멤버 테스트
  • 변경 불가능
  • 튜플 패킹/언패킹
  • 패킹
  • 한 튜플 안에 여러 데이터를 넣는 것
  • T = 1, 2, 3
  • 언패킹
  • 튜플에서 데이터를 분리해 내는 것
  • x, y, z = T
  • 패킹, 언패킹은 리스트에도 적용됨.
  • 가변인자는 나타내는 방법
  • *파라미터
  • 튜플과 리스트 상호 변환
  • list() , tuple()
  • 튜플을 사용하는 경우
  • 함수가 하나 이상의 값을 반환하는 경우
  • 문자열 포맷팅
  • 가변 인수 지원
  • 그 이외, 고정된 값을 표현하기 위하여
  • 튜플 사용예들
  • os.path.split(path) 와 os.path.splitext(path)의 결과
  • URL 다루기(urlparse 모듈)
  • urlparse() - url을 각 성분별로 분리, 튜플 반환
  • urlunparse() - url성분을 하나의 url로 역 변환, 튜플 인자
  • urljoin(base, url)
  • 베이스 url과 상대 url을 연결하여 절대 url 생성

7장 - 사전

  • 사전 객체의 기초 연산
  • 사전 만들기
  • dict = {k1:v1}
  • 키와 값
  • 키는 변경 불가능한 객체 이어야 함.
  • 키는 기본 객체로 문자열, 숫자, 튜플이 가능
  • 리스트와 사전은 키가 될 수 없다.
  • 사전 객체의 메쏘드
  • 가장 많이 사용하는 메소드
  • keys() - 키 리스트
  • values() - 값 리스트
  • items() - (키, 값) 리스트
  • has_key(key) _ 키가 있는가?
  • 기타 메소드
  • clear() - 항목 모두 삭제
  • copy() - 사전 복사
  • get(key[, x]) - 키가 없으면 x를 취한다.
  • setdefault(key[, x]) - 키가 없으면 x를 키에 설정한다.
  • update(D) - D 사전의 내용으로 갱신
  • popitem()- (키, 값)을 리턴하고 항목을 제거
  • key 찾기
  • <key> in <사전>
  • <사전>.has_key(<key>)
  • 심볼 데이블
  • 정의 : 심볼(이름)에 대한 값이 저장된 데이블
  • 전역/지역 심볼 테이블
  • globals() - 전역
  • locals() - 지역
  • 객체의 심볼 테이블
  • __dict__ 속성
  • 함수에도 변수를 정의 할 수 있다.
  • 사전을 for문으로 참조하기
  • keys()
  • items().sort() - key로 정렬

8장 - 객체의 복사 및 형 변환

  • 레퍼번스 복사
  • 객체의 참조 주소를 복사하는 것
  • 가장 일반적인 변수 대입
  • copy 모듈을 이용한 복사
  • 얕은 복사(shallow copy)
  • 복합 객체를 복사하되 내용은 원래의 레퍼런스로 채운다.
  • copy.copy(x)
  • 깊은 복사(deep copy)
  • 복합 객체를 생성하고 내용을 재귀적으로 복사한다.
  • copy.deepcopy(x)
  • 사전과 같은 복사 기능이 없는 객체를 복사하는데도 유용
  • 리스트 <-> 사전
  • 사전 -> 리스트
  • keys(), values(), items()
  • 리스트 -> 사전
  • L = [(‘one’,1), (‘two’,2), (‘three’, 3)]
    D = {}
    for k, v in L:
      D[k] = v
  • zip() 함수 이용한 방법
  • keys = [‘one’,’two’,’three’]
    values = [1, 2, 3]
    zip(keys, values)
  • 문자 <-> 코드값
  • chr() : ascii code -> character
  • ord() : character  -> ascii code
  • 진법 변환
  • int() - 10진수로
  • int(‘64’, 16) # 16진수 ‘64’를 10진수로
  • int(‘144’, 8) # 8진수 ‘144’를 10진수로
  • int(‘101’, 2) # 2진수 ‘101’를 10진수로
  • oct() - 8진수로
  • hex() - 16진수로
  • 2진수로 ?
  • 임의 진수로
  • 정수를 콤마가 있는 문자열로 변환
  • >>> import locale
    >>> locale.setlocale(local.LC_ALL, “”)
    >>> print locale.format(“%d”, 10030405, 1)
    ‘10,030,405’

9장 - 파일

파일 읽기

  • 관련 메소드
  • readline() - 한 줄을 읽는다.
  • 더이상 읽을 것이 없으면 None 반환
  • readlines() - 전체를 줄 단위로 읽어 리스트에 저장
  • 너무 크면 문제가 발생 할 수 있다. 느리게 된다.
  • xreadlines() - readlines()와 동작은 동일 하지만 필요한 만큼만 처리한다.
  • 파일 객체의 반복자
  • for line in fobj:
      print line

라인 단위로 파일 쓰기

  • 메소드목록
  • write(s) - 문자열 s 쓰기
  • writelines(lines) - 문자열 목록 쓰기

임의 접근 파일

  • 원하는 위치의 내용을 마음대로 읽느다.
  • seek(n)
  • n 번째 바이트로 이동
  • seek(n, 1)
  • 현재 위치에서 n 바이트 이동
  • seek(n, 2)
  • 맨 마지막에서 n 바이트 이동 (n은 보통 음수)
  • tell()
  • 현재 파일 위치 리턴

추가 파일 메쏘드들

  • file.flush() : 버퍼가 다 채워지지 않았어도 내부 버퍼의 내용을 파일에 보낸다.
  • file.fileno() : file 객체의 파일 기술자(FD) 정수를 반환 한다.
  • file.isatty() : 만일 file 객체가 tty와 같은 장치이면 True아니면 False을 반환
  • file.truncate([size]) : 파일 크기를 지정된 크기로 잘라버림.
    인수를 주지 않으면 현재 위치에서 자른다
  • file.closed : file이 close 되었으면 True 아니면 False
  • file.mode : 파일의 오픈된 mode
  • file.name : open() 할 때 사용된 파일 이름
  • file.softspace : True 이면 print문을 사용할 때 값 출력 사이에 자동적으로 space가 출력됨.
    False 이면 space가 자동으로 삽입되지 않음

표준 입출력 방향 전환

  • sys.stdout 를 사용하여
  • StringIO 모듈를 사용하여 문자열 처리 사용한다.

지속 모듈

  • 어떤 시점의 데이터를 저장해 두었다가 나중에 다시 사용할 수 있도록 한다.
  • 관련 모듈
  • DBM 관련
  • dbm 스타일의 데이터 베이스 모듈들
  • anydbm, dbm, gdbm, dbhash, dumbdam
  • 키와 값을 모두 문자열이어야 함.
  • pickle 모듈
  • 파이썬 일반객체를 파일에 저장하는 모듈
  • 재귀적인 관계의 객체도 모두 처리한다.
  • 이진 모드 피클링 가능 함.
  • dump(obj, file, True)
  • marshal 모듈
  • 파이썬의 기본 객체를 이진포맷으로 저장
  • 재귀적인 구조는 처리할 수 없다
  • 주로 .pyc 컴파일 코드를 읽는데 사용됨
  • pickle 모듈과 사용법이 같음
  • shelve 모듈
  • dbm 모듈과 유사함.
  • pickle을 이용하여 값을 저장하므로 임의의 객체를 저장할 수 있다.
  • cPickle 모듈
  • pickle과 동일하지만 빠르다 (1000배)

10장 - 함수

요약

  • 함수 반환값 아래와 같은 규칙이 있음.
  • 인수 없이 리턴하면 내부적으로는 None인 반환 되는 것이다.
  • return 문 없이 리턴하면 None 반환 된다.

스코핑 룰

  • LGB rule(작은 곳부터 큰 곳으로)
  • Local -> Global -> Built-in
  • global 명시적으로 글로벌 네임 변수로 지정
  • 내장 영역 이름 알아보기
  • dir(__builtins__)
  • 중첩 영역(nested scopes)
  • list응용하여 오류를 처리할 수 있다.

함수 인수

  • 가변 인수 리스트 : 형식
  • 고정 인수 다음에 가변 인수는 적는다.
  • *<가변인수> : 리스트 형식
  • **<가변인수> : 딕셔너리 형식
  • 함수의 가인수 나열 순서
  • 순서에 의한 인수
  • 가변 인수
  • 사전 키워드 인수
  • 튜플을 이용한 함수 호출 예)
  • >>> def h (a, b, c):
      print a, b, c
    >>> args = (1, 2, 3)
    >>> h(
    *args)
    1 2 3
  • 사전을 이용한 함수 호출
  • >>> dargs = {‘a’:1, ‘b’:2, ‘c’:3}
    >>> h(
    **args)
    1 2 3

람다(lambda) 함수

  • 한 줄 짜리 이름 없는 함수
  • 형식> lambda 콤마로 구분된 인수들: 식
  • 예)
  • >>> lambda:1
    >>> f = lambda:1
    >>> f()
    1
  • >>> g = lambda x, y : x + y
    >>> g (1,2)
    3
  • 적용 범위
  • 함수를 인수로 넘겨야 하는 경우
  • 일반함수와 차이

구분

일반함수

람다함수

문/식

statement(문)

expression(식)

함수의 이름

함수 이름을 사용가능

함수 객체만 생성

몸체

한 개 이상의 문

하나의 식만 옴

반환

return 문으로 명시적 지정

식의 결과가 반환

내부 변수 선언

지역 변수 생성 가능

지역 변수 생성 불가

함수적 프로그래밍

  • 정의
  • Haskell에서 영향을 받음
  • 함수를 중심으로 한 프로그래밍
  • 명령적, 절차적이기 보다는 표현식(expression)에 중심을 둔 프로그래밍
  • 함수는 first-class 함수로 다른 함수의 인수로 전달될 수 있고, 자료구조에 저장될 수도 있다.
  • 함수적 프로그래밍에서 사용되는 함수들
  • map, zip, filter, reduce, apply
  • map 내장 함수
  • X = <리스트>
    Y = map(lambda a:a*a, X)
  • 이미 존재하는 연산자의 경우 operator 모듈를 사용하여 함.
  • 순서쌍 만들기
    >>> a = [1, 2, 3]
    >>> b = [100, 120, 130]
    >>> map (None, a, b)
    [(1,100), (2,120), (3,130)]
    ** 짝이 맞지 않으면 None으로 채워짐.
  • zip을 사용하는 방식 , 람다부분이 없고 동일함.
    >>> zip(a, b)
    [(1,100), (2,120), (3,130)]
    ** 맞지 않으면 버린다.
  • filter 내장 함수
  • 필터 함수를 통하여 참인 요소만 모은다.
    >>> filter(lambda x:x%2, [1,2,3,4,5,6})
    [1,3,5]
  • 사용예 1) 문자열 리스트에서 공백을 문자열 제거 할 때
    L = filter(None, L)
  • reduce 내장 함수
  • reduce(f , <테이터> ,<초기값>)
  • 테이터의 누적치 연산
    >>> reduce(lambda x,y:x+y , range(1,11))
    55
  • apply 내장 함수
  • *args 비슷한 역할을 수행
  • 사용예)
    >>> def f(a,b,c):
         print a,b,c
    >>> args = (1,2,3)
    >>> apply(f, args)
    1 2 3
    ** 2.x 이상에서는 f(*args)로 대체 가능 함.

11장 - 모듈

모듈이란

  • 정의
  • 파이썬 프로그램 파일 혹은 C확장 파일
  • 프로그램(함수, 클래스)과 데이터를 정의
  • 라이브러리 와 비슷한 개념
  • 모듈의 종류
  • 표준모듈
  • 사용자 생성 모듈
  • 써드파티 모듈
  • 파이썬 모듈
  • .py 확장자를 갖는 파이썬 코드를 저장한 파일

이름 공간

  • 이름(변수)이 저장되는 공간, 사전 형식으로 저장됨
  • 변수 분류
  • 자격 변수(qualified variable) : 이름공간이 명백히 주어진 변수
  • 무자격 변수(unqualified variable) : 공간이 명확하지 않는 것 (LGB 룰)
  • globals() - 전역 공간 이름 확인 할 수 있으며 변경도 가능 함.
  • locals() - 지역공간의 이름들을 확인 가능 함. 그러나 되도록 변경하지 않는 것을 권장
  • vars() - __dict__ 의 값을 반환함.
  • 모듈의 이름 공간 알아보기 - dir()
  • 모듈의 이름 공간 얻기 - __dict__ , 관련 vars()
  • 이름 공간을 갖는 것들
  • 모듈, 함수, 클래스, 클래스 인스턴스
  • 외부에서 값을 설정하는 것도 가능

모듈 검색 경로

  • PYTHONPATH - 환경 변수 참고
  • sys.path - 모듈 검색 패스 정보
  • 변경 가능 함

import에 대해서 좀더 알아보기

  • 모듈 import 방법들
  • import sys
  • from sys import path
  • from sys import *
  • import sys as system
  • from sys import path as pythonpath
  • import는 코드도 수행 한다.
  • 컴파일과 loading 시간
  • 파일 검색 순서 .pyc -> .py
  • 쓰기 권한이 없다면 .pyc는 생성되지 않고 메모리에 직접 loading 됨.
  • .pyc가 있다면 loading 시간이 감소됨.
  • bytecode를 source 코드로 역변환 하기
  • decompyle 이용하기 (링크)
  • 디컴파일 불가능하게 하는 모듈
  • py2exe -> 파이썬 배포가 필요없음.
  • 문자열로 표현된 모듈 가져오기
  • __import__(<모듈이름>)
  • 모듈은 공유됨 : 즉 한번 import된 계속 공유됨.
  • 모듈을 재적재
  • reload(<모듈명>)
  • 변경됨 모듈 정보를 초기화 할 때 사용됨.

모듈의 실행

  • __name__ 속성을 이용하여 최상위 모듈인지 import 되는 모듈인지 구분
  • 자기 모듈이름을 출력 import 될 때
  • 모듈이 실행될 때 __main__

문자열 이름으로 속성값 참조하기

  • getattr(<obj>, ‘속성명’) : 해당 속성에 해당하는 것을 반환
  • setattr() : 해당 객체에 속성을 설정
  • hasattr() : 속성값 갖고 있는 여부
  • delattr() : 해당 속성을 삭제

패키지(Package)

  • 정의
  • 모듈을 조직하는 상위 구조
  • 여러 관련 모듈을 계층적 디렉토리에 모아 하나의 패키지를 만든다
  • 각 디렉토리에는 __init__.py 파일이 있어 패키지를 초기화 하는데 사용됨.
  • __init__ 파일
  • 패키지에서 사용할 함수, 변수, 모듈등을 정의 한다.
  • from <패키지> import * 를 사용하여 패키지 하위 모듈 혹은 부 패키지를 포함하려면
    __all__ 변수에 그 목록을 기술해야 한다.
  • 자연스럽게 사용하려면 다음과 같이 정의

Speech/__init__.py
__all__ = [
'Synthesis', 'Recognition', 'SignalProcessing']

import Recognition
import Synthesis
import SignalProcessing
----------------------------------
Speech/Recognition/__init__.py
__all__ = [
'HMM', 'NN', 'DTW']
import HMM, NN, DTW
...

12강 - 클래스

클래스의 정의

  • 하나의 이름 공간
  • 상속 지원
  • 연산자 중복지원

클래스의 용어 정리

  • 클래스 - 자바 클래스와 비슷
  • 클래스 인스턴스(객체)
  • member - 클래스가 갖는 변수
  • method - 클래스 내에 정의된 함수
  • attribute - member 와 method
  • superclass , baseclass : 상위 클래스
  • subclass, derived class : 하위 클래스

클래스 정의

class Simple:  # header
   
pass       # body

  • 클래스와 인스턴스 객체는 각각 독립적인 이름 공간을 갖는다.

메소드 정의하기

  • 일반 함수를 정의하는 것과 동일
  • 첫 인수로 인스턴스 객체를 온다
  • self는 인스턴스 객체를 가리킨다(java의 this와 비슷)
  • 메쏘드 호출하기
  • bound instance method 호출

>>> c = MyClass()
>>> c.set('egg')
>>> c.put()

  • unbound instance class method 호출

>>> MyClass.set(c, 'egg')
>>> MyClass.put(c)

  • 정적 메소드(static method)
  • 인스턴스 객체 없이 클래스에서 직접 호출할 수 있는 메소드

>>> class D:
   
def spam(x, y): #self가 없다.
     
print 'static method', x, y
   spam = staticmethod(spam)

  • 호출예)
    D.spam(1, 2)
  • 클래스 메쏘드(class method)
  • 첫 인수로 클래스 객체를 받는다.

>>> class C:
   
def spam(cls, y):
       
print cls, y
   spam = classmethod(spam)
>>> C.spam(5)

생성자 와 소멸자

  • __init__(self)
  • __del__(self)

연산자 중복

  • 수치 연산자 메소드

method

피연산자 위치 반대

opeator

__add__(self, o)

__radd__(self, o)

+

__sub__(self, o)

__rsub__(self, o)

-

__mul__(self, o)

__rmul__(self, o)

*

__div__(self, o)

__rdiv__(self, o)

/

__floordiv__(self, o)

__rfloordiv__(self, o)

//

__mod__(self, o)

__rmod__(self, o)

%

__divmod__(self, o)

__rdivmod__(self, o)

divmod()

__pow__(self, o, module)

__rpow__(self, o, module)

pow(), **

__lshfit__(self, o)

__rlshfit__(self, o)

<<

__rshift__(self, o)

__rrshift__(self, o)

>>

__and__(self, o)

__rand__(self, o)

&

__xor__(self, o)

__rxor__(self, o)

^

__or__(self, o)

__ror__(self, o)

|

  • __coerce__
  • 다른 두 자료형에 수치 자료형이 적용될 때 두 자료형을 조정해주는 메쏘드
  • 수치 연산자 메소드를 구현 역할은 한다.
  • 기타 수치 연산자 중복
  • 단항 연산자 메소드

method

opeartor

__neg__(self)

-

__pos__(self)

+

__abs__(self)

abs()

__invert__(self)

~ 비트 반전

  • 형 변환 메소드

method

operator

__complex__(self)

complex()

__int__(self)

int()

__long__(self)

long()

__float__(self)

float()

  • 8진수 16진수 변환 메소드

method

operator

__oct__(self)

oct()

__hex__(self)

hex()

  • 시퀀스 자료형의 연산자 중복

method

operator

__len__(self)

len()

__contains__(self, item)

in 연산자 사용시 호출

__getitem__(self, key)

self[key]

__setitem__(self, key, value)

self[key] = value

__delitem__(self, key)

del self[key]

  • 슬라이싱
  • slice 객체 : slice([start,] stop [, step])
  • 매핑 자료형의 연산자 중복

method

operator

__len__(self)

len()

__getitem__(self, key)

self[key]

__setitem__(self, key, value)

self[key] = value

__delitem__(self, key)

del self[key]

 

특별한 메소드들

  • __repr__(self)
  • repr() 혹은 ‘’에 의해 호출
  • 문자열 반환한다. (자바의 toString()와 비슷)
  • __str__(self)
  • print 혹은 str()에 의해 호출
  • 문자열 반환한다. (자바의 toString()와 비슷)
  • __cmp__(self, other)
  • 비교 연산 (<, >, <=, >=, ==, !=)에 의해 호출
  • -1, 0, 1을 리턴한다.
  • 비교 연산을 위한 메소드들

operator

method

<

__lt__

<=

__le__

>

__gt__

>=

__ge__

==

__eq__

!=

__ne__

  • __hash__(self)
  • 객체 m이 사전의 키로 사용될 때 해쉬 키 값을 얻을 때 호출된다.
    32bit 정수를 리턴해야 한다. __cmp__ 메소드도 함께 정의되어
    있어야 한다.
  • __nonzero__(self)
  • 객체의 진리값을 결정한다. 0 또는 1를 반환
  • __call__(self[, args…])
  • 호출 가능한 클래스 인스턴스 만들기
  • __slots__
  • 허용 가능한 인스턴스 변수 목록 만들기
  • 이 곳에 선언되어 있는 변수들만 선언될 수 있다.
  • get/set 메쏘드로 속성 정의하기(property)

class D(object):
 
def __init__(self):
      self.__degree =
0
 
def get_degree(self):    # degree를 읽을 때 호출됨.
     
return self.__degree
 
def set_degree(self, d):    # degree를 기록할 때 호출됨.
      self.__degree = d %
360
  degree = property(get_degree, set_degree)

  • 클래스 인스턴스 속성 제어하기
  • 인스턴스 객체 속성을 다루기 위한 메소드들

method

description

__getattr__(self, name)

정의되어 있지 않는 속성을 참조할 때, 이 메쏘드가 호출된다. 속성 이름 name 문자열이다.

__getattribute__(self, name)

__getattr__ 과 같으나 속성이 정의되어 있어도 호출된다.

__setattr__(self, name, value)

self.name = value와 같이 속성에 치환(대입)이 일어날 때 호출된다.

__delattr__(self, name)

del self.name 시에 호출된다.

상속

  • 다중 상속 지원함.
  • 형식 : class B (A, C):
  • 메쏘드 처리 순서
  • 다이아몬드형 다중 상속 #1
  • 다이아몬드형 다중 상속 #2
  • 메쏘드 처리 순서(MRO-method resolution order)
  • super(클래스, self).xxxx() 메소드를 사용하여 해결 함.
  • 가상함수
  • 메소드의 호출이 참조되는 클래스 인스턴스에 따라서 동적으로 결정되는 함수
    (dynamic binding)
  • 파이썬 클래스의 모든 메스도는 가상 함수
  • 명령어 해석기 관련 유용한 클래스
  • cmd.Cmd 부클래스 작성
  • 수퍼 클래스의 생성자 rootine 수행
  • 프롬프트 모양을 지정(prompt)
  • 명령어 정의하는 법
  • 명령어 : do_명령어
  • 도움말 : help_명령어
  • 명령어 해석기 실행
  • cmdloop() 메소드 실행
  • 상속 관계 정보
  • isinstance() : 객체가 어떤 클래스에 속하는 지
  • issubclass() : 클래스 간의 상속 관계
  • __bases__ : 수퍼 클래스 목록 얻기
  • __class__ : 인스턴스 객체의 클래스 알아내기
  • __dict__ : 클래스 객체와 인스턴스 객체의 이름 공간 얻기

협동적 클래스와 super

  • 정의 : 상속 관계에 있는 클래스들이 super 콜을 이용하여 협동적으로 하나의 작업을 수행하는 것
  • super를 이용하면 협동적 일을 쉽고 간결하게 해결
  • super(<자신의 클래스 이름>, self).<메소드>()
  • 수퍼클래스를 지정하지 않아도 MRO(Method resolution order)에 따라서 수퍼클래스의 메소드를 자동으로 호출함
  • 단, 최상위 클래스는 object의 sub 클래스이어야 함.

내장 자료형과 클래스

  • 자료형 이름과 생성자 일치 : 자료형 이름과 생성자 이름이 같다
  • 내장 함수에서 변경된 팩토리 함수로서의 내장 자료형

내장 자료형

description

int(number_of_string[, base_number])

int(‘123’)

long(number_of_string)

long(‘1234’)

float(number_of_string)

float(‘123.45’)

complex(number_of_string[, imag_number])

complex(‘3+4j’)

str(obj)

str(123)

unicode(string[, encoding_string])

unicode(‘abc’)

tuple(iterable)

tuple(‘spam’)

list(iterable)

list(‘spam’)

type(object) 또는
type(name_string, base_tuple, methods_dict)

type(‘spam’)

  • 새로추가된 팩토리 함수로서의 내장 자료형

내장 자료형

description

dict()

사전 객체를 생성

object()

모든 내장 객체의 베이스 클래스인 object 객체를 생성

classmethod(function)

클래스 메쏘드 생성

staticmethod(function)

정적 메쏘드 생성

super(class_or_type, instance)

property(get_function[, set_function])

  • 클래스 형과 자료형의 일치 : 클래스 이름 곧 자료 형이다.

추가 설명들

  • 다형성
  • 같은 이름이 여러 행동이 한다는 뜻
  • 상속과 합성
  • is-a : 상속
  • has-a : 합성
  • 캡슐화
  • 필요한 메소드와 멤버를 하나의 단위로 묶어 외부에서 접근 가능 하도록 인터페이스를 제공하는 것
  • 캡슐화 방식
  • 비공개 방식(black box)
  • 공개 방식(white box) --> 파이썬 방식
  • 정보 은닉
  • 정보를 숨기는 것
  • private 이름 변경 기능
  • __ 로 시작하는 이름을 정의. 앞에 _클래스 이름이 추가됨.
  • 내부적인 이름들을 _로 시작하여 내부(private)임을 나타냄.
  • 위임
  • 상속 메카니즘 대신 사용되는 기법
  • 자신이 처리하지 않고 다른 객체에 전달
  • 구현
  • __getattr__을 이용
  • 정의되지 않은 속성을 참조할 때 호출
  • 형식 : __getattr__(self, name)

class Delegation():
 
def __init__(self, data):
      self.stack = data
 
def __getattr__(self, name):
     
print 'Delegating %s ..' %name,
     
return getattr(self.stack, name)

a = Delegation([
1, 2, 3, 1, 5])
print a.pop()
print a.count(1)

  • 문서 문자열 : 클래스나 메소드 몸체에 처음으로 오는 문자열은 문서 문자열로 간주됨.

class Delegation():
 
def __init__(self, data):
      self.stack = data
 
def __getattr__(self, name):
     
print 'Delegating %s ..' %name,
     
return getattr(self.stack, name)

a = Delegation([
1, 2, 3, 1, 5])
print a.pop()
print a.count(1)

기타

  • ** TypeError: 'module' object is not callable

13강 - 예외 처리

try/exception/else 절

  • 자바와 비슷하지만 else 구문은 파이썬에만 존재 함.

try/finally 절

  • 자바와 동일하다

예외 발생 시키기

  • 문자열 정의 사용자 예외 발생
  • 예)

>>> MyException = 'my exception'
>>> def dosomething():
       
raise MyException, 123
>>> try:
       domsomething()
   
except MyException, param:
       
print 'Exception occured', param

  • rasie 구문을 사용하여 예외를 발생 시킴
  • 사용자 정의 클래스 예외 만들기
  • class MyException(Exception):
  • assert 문으로 예외 발생 시키기
  • 형식 : assert <테스트코드>, <데이터>
  • <테스트코드>가 거짓이면 ‘raise AssertionError, <데이터>’ 예외가 발생
  • 파이썬 -O 옵션으로 실행하면 컴파일된 바이트 코드로 부터 삭제됨.

14강 - 약한 참조, 반복자, 발생자

약한 참조(weak reference)

  • 레퍼런스 카운트로 고려되지 않는 참조를 의미
  • 사용목적 : 순환 참조로 인한 가비지 컬렉터 기능를 방해 되지 않도록 하기 위해서
  • 참조되는 객체 삭제시 같이 삭제됨.
  • weakref 모듈
  • weakref.ref() - 약한 참조 객체 생성
  • weakref.proxy() - 프록시 객체 생성
  • weakref.WeakValueDictionary()
  • weakref.WeakKeyDictionary()
  • weakref.getweakrefcount(obj) - 약한 참조의 개수 알아보기
  • weakref.getweakrefs(obj) - 약한 참조 객체 얻기

약한 사전(weak dictionary)

  • 캐쉬(cache)라고도 한다.
  • 키(key) 혹은 값(value)으로 사용되는 객체는 약한 참조가 가능해야 함.
  • 사전의 키(key) 혹은 값(value)으로 약한 참조를 갖는다.
  • 객체가 삭제되면 자동으로 캐쉬에 있는 키, 값 도 삭제된다.
  • WeakValueDictionary - 값으로 약한 참조를 갖는다.
  • WeakKeyDictionary - 키으로 약한 참조를 갖는다.

반복자

  • 기본 인텍싱의 문제점
  • 반드시 indexing 필요하지 않는 경우에는 __getitem__ 불필요하다.
    즉 index 정보를 관리 해야 하므로
  • 반복자를 한 번에 많을 정보를 메모리에 올릴 필요가 없으므로 대용량 처리 할 때 좋다.
  • 반복자 객체
  • iter() 내장 함수로 만들어짐
  • next() 메소드를 갖음
  • next() 메소드가 더 이상 자료를 넘겨줄 수 없는 경우에는 StopIteration 예외를 발생함.
  • for문은 반복자 객체에 의해 수행됨.
  • 클래스에 반복자 구현하기
  • __iter__ 을 구현하고 next() 메소드가 있는 객체를 리턴한다
  • 클래스 자체를 반복자로 만들려면 next() 메소드를 구현한다
  • 사전의 반복자
  • 사전은 그 자체가 키에 대한 반복자이다
  • iterkeys, itervalues, iteritems 메소드는 키, 값, 튜플(키, 값) 반복자를 반환함.
  • 파일 객체의 반복자
  • 파일 객체는 행 단위 반복자를 지원함.
  • 호출 가능한 객체에 반복자 적용하기
  • for val in iter(callable, endval): <수행할 문장>
  • callable이 endval 값을 리턴할 때 까지 <수행할 문장>을 반복

발생자

  • 정의
  • 함수가 호출된 후에 되돌아 갈 때, 메모리가 해제되지 않고 그대로 남아있음.
  • 다시 그 함수가 호출될 때 이 전에 수행이 종료되었던 지점 이후를 계속 진행
  • 반복자 기능도 수행 함.
  • 관련 키워드 : yield
  • 예제

>>> from __future__ import generators
>>> def generate_ints(N):
       
for i in range(N):
           
yield i
>>> gen = generate_ints(10)
>>> gen
<generator object at
0x01370B30>
>>> gen.next()
0
>>> gen.next()
1
>>> for k in gen:
     
print k,
2 3 4 5 6 7 8 9

  • 트리 탐색 소스를 확인 할만 하다.

15강 - web 서버, client 프로그래밍

관련 web 사이트들

  • 링크 #1 : Link -> 원도 IIS용
  • 링크 #2 : Link -> AutoSet (아파치 웝서버 응용)

파이썬 cgi 실행시 스크립트 설정

  • 원도우
  • #!c:\Python27\python.exe
  • #-*- coding: utf-8 -*-
  • 유닉스
  • #!/usr/bin/python

cgi 프로그램 디버깅

  • 관련 코드 예제

import cgitb
cgitb.enable()
# 파일로 로그를 저장하려면 다음과 같이
cgitb.enable(display=
0, logdir='/tmp')
# display=0 , web 브라우저에 표시 하지 않는다.
# logdir는 반드시 디렉토리명 이어야 한다. 로그 파일명 아님.
# 기록된 로그는 html 파일 형식 임.

  • 주의 사항 -
  • 정상적인 디버깅 페이지가 나오게 하기 위해서는 정상적인 페이지 구성을 해야 한다
  • ie 11에서는 잘 보이지만 다른 브라우저(크롬, 파이어복스)에서는 코드 전체가 보인다.

cgi로 전달된 파라미터 읽기

  • get, post 상관 없음
  • 예제

import cgi
form = cgi.FieldStorage()
print form.keys(), form,values()

# 값을 읽는 방법
print form['email'].value  # 주의 email 필드가 없으면 exception 발생
email = form.getvalue(
'email','') # email 필드가 없어도 에러가 발생하지 않는다.

CGI 환경 변수 출력

  • cgi.test()
  • 각종 환경 변수를 출력한다. html 형식으로

파이썬 DB 모듈들

  • Python DB API Spec 2.0
  • DB별 모듈 조사 하기
  • 각 DB 제조사별로 연동에 대한 자료 수집
  • maria db
  • mysql db

MySQL DB 관련 파이썬 모듈

  • MySQLdb
  • 모듈 명 : MySQL-python
  • 관련 사이트들
  • 설치 결과
  • 설치 오류 발생함
  • 관련 명령어 : pip install MySQL-python
  • 모듈 : PyMySQL
  • pip install PyMySQL
  • 설치 잘됨 , 테스트 완료함.
  • 관련 설명 사이트 많음.
  • 사이트들
  • 시험 코드 작업 시 발생한 오류
  • pymysql.connect()의 charset 속성값 오류 발생함 -- 버그 잡는데 많이 시간이 발생함.
  • utf8을 utf-8 이라고 입력 함. 주의 **
  • Mysql 공식 사이트
  • 관련 사이트 : 공식 사이트는
  • 모듈명 : MySQL
  • 현재 원도우용은 문제가 있음
  • mysql community 8.x 이후 지원하는 것 같음.

MSSQL DB 연동 관련

  • 참고 사이트
  • 연동 관련 모듈들
  • pymysql
  • 추후 시험 하자

urllib 모듈 (3.x 에서는 제거됨)

  • URL 조작
  • URL 인코딩 - urlencode
  • URL Quoting - quote
  • URL Unquoting - unquote
  • 파일 가져오기 (urlopen)
  • http 파일 가져오기 (http:)
  • ftp 파일 가져오기 (ftp:)
  • 로컬 디스크의 파일 가져오기 (file:)
  • 웹에서 읽은 파일 직접 저장하기
  • urlretrieve(url[, filename[, reporthook[, data]]])

httplib 모듈

  • HTTP 서버와 좀더 섬세한 통신을 수행할 때 사용
  • 헤더에 쿠키 정보를 포함시킬 때
  • 인증 정보등을 포함해서 전송해야 할 경우
  • web 브라우저 타입을 보내야 할 경우

16강 - 이메일 보내기/읽기

메일 프로토콜

  • SMTP
  • Simple Mail Transfer Protocol
  • 메일 전송 프로토콜
  • TCP/UDP 25번 포트 사용
  • 규약 : RFC-821

  • POP3
  • Post Office Protocol Version 3
  • 메일 수신 프로토콜
  • 수신인의 메일박스에서 사용자의 메일을 가져오는 프로토콜
  • TCP 110 포트 사용
  • 규약 : RFC-821
  • IMAP4
  • Internet Message Access Protocol Version 4
  • 메일 수신 프로토콜
  • POP3와 기본 기능은 동일
  • POP3의 단점을 보완
  • 원격지 서버에서 모든 메일을 관리
  • 자신의 컴퓨터의 메일 처리 관리 가능
  • 메일 허더만 따로 가져오는 것이 가능
  • 제목만 통해 선택적으로 메일을 살펴볼수도 있다.
  • 특정 MIME 내용만 가져올 수 있는 기능

  • MIME
  • Multipart Internet Mail Extensions
  • 다국어 문자, 멀티미디어 데이터를 함께 전송하도록 기능이 확장된 프로토콜
  • 영문자 중심을 전송을 확장함
  • 여러 파트로 구성되고 각 파트는 별도의 데이터를 포함함.
  • 재귀적으로 포함 가능함.

파이썬 메일 관련 모듈들 (2.x 기준)

  • smtplib
  • poplib
  • pop3 포함
  • imaplib
  • IMAP4
  • email (2.2)

메일 전송 개발 환경 정보 (Gmail)

smtplib 모듈 사용하기

텍스트 문자열 구성하기

  • email.MIMEText 모듈 이용
  • class MIMEText(_text[,_subtype[,_charset[,_encoder]]])
  • _text : 변환할 문자열
  • _subtype : minor type(plain)
  • _charset : 문자셋(us-ascii)
  • _encoder : 7 or 8 (7)
  • msg = MIMEText(contents,_charset=’euc-kr’)
  • 기타 필요한 헤더 정보 추가 (Subject, From , To)
  • msg.as_string()/ str(msg)
  • sample code

# file-name: SendMailEx.py
# -*- coding:utf-8 -*-
# 메일 전송 하기
import smtplib
from email.mime.text import MIMEText

smtp = smtplib.SMTP_SSL(
'smtp.daum.net', 465)
smtp.ehlo()    
# say Hello
# smtp.starttls() #TLS 사용시 필요

smtp.login(
'cosmoslight', '----')
body =
'''
이것은 말이죠 정말 멋진 내용의 메시지 입니다
그러나 잘 표시 될지는 모르 겠네요. 표시되어야 하는데2x3'''

msg = MIMEText(body)
msg[
'Subject'] = '시험중'
msg[
'From'] = 'cosmoslight@daum.net'    # 이분을 반드시 입력 해야 한다.
msg[
'To'] = 'cosmoslight.huni@gmail.com'
x = smtp.sendmail(
'cosmoslight@daum.net', 'cosmoslight.huni@gmail.com', msg.as_string())
print(msg.as_string())
smtp.quit()

첨부 파일 보내기

  • 전체 MIME 메시지 객체 생성
  • from email.MIMEBase import MIMEBase
    outer = MIMEBase(‘multipart’, ‘mixed’)
    outer.attach(msg) # MIME 메시지 추가
  • 개별 MIME 메시지 생성

3.x 와 2.x는 import 방식이 다름. 주의
msg = MIMEText(텍스트_문자열, _charset=
'euc-kr')
msg = MIMEImage(이미지_문자열, _subtype=subtype)
msg = MIMEAudio(오디오_문자열, _subtype=subtype)

  • 기타 메시지 생성

from email import Encoders
msg = MIMEBase(maintype, subtype)  
# 객체를 만들고
msg.add_payload(데이터_문자열)
# 내용을 덧 붙이고
Encoders.encode_base64(msg)
# 인코딩 한다.

인코딩

  • email.Encoders
  • quoted_printable(msg)
  • Quoted-printable로 인코딩하고 Content-Transfer-Encoding 헤더
    quoted-printable로 설정
  • ASCII 문자는 그대로 전송
  • 그 이외의 문자는 세 개의 문자로 변환해서 전송
  • 변환 방법은
  • ‘=’ + ASCII로 두 바이트로 16진수를 표현
  • 10011101 -> =9D
  • encode_base64(msg)
  • Base64로 인코딩하고 Content-Transfer-Encoding 헤더 base64로 설정
  • 데이터를 24비트(3바이트) 블록으로 분리
  • 이것은 다시 6비트 네 개로 분리
  • 각 6비트는 8비트 ASCII 문자로 변환
  • A-Z, a-z, 0-9, +, / 총 64개의 문자로 구성
  • 000100 -> ‘E’
  • encode_7or8bit(mg)
  • Content-Transfer-Encoding 헤더를 7bit 혹은 8bit로 설정
  • encode_noop(msg)
  • 아무일도 하지 않는다.

이메일 읽기

  • 메일 가져오기
  • POP3를 이용하여 메일을 읽어오기
  • 초기화 / 종료 방법

17강 - Socket 프로그래밍

Socket 개요

  • 특징
  • 양방향
  • 포트번호
  • 하나의 전송선에 여러 개의 응용프로그램을 실행하기 위해 포트 개념 도임
  • 포트번호 : 0 ~ 65535
  • 잘 알려진 서비스 번호 : 1 ~ 255
  • 그 밖의 예약 : 256 ~ 1023
  • 임시 클라이언트 : 1024 ~ 4999
  • 사용자 정의 포트 번호 5000 대 이후를 사용하라
  • 인터넷 서비스 포트 번호 알아보기
  • 리눅스 : /etc/services 파일 확인
  • 파이썬 함수를 이용하기
  • socket.getservbyname(<servicename>,<protocolname>)
  • 예) socket.getservbyname(‘http’,’tcp’)
  • 종류
  • Domain
  • AF_UNIX : c/s는 동일 기계에 존재 (유닉스 도메인 소켓)
  • AF_INET : c/s는 다른 기계에 존재할 수 있다(IP 소켓)
  • Type
  • SOCK_STREAM : TCP 소켓
  • SOCK_DGRAM  : UDP 소켓

Socket 객체의 기본 메소드

  • 서버측
  • 클래스 socket() : 소켓 객체를 생성
  • 메소드들
  • bind((host, port))
  • listen(n) : n 의 동시 접속 클라이언트 허용
  • accept() : 접속 허용
  • recv(bufsize) : 데이타 수신
  • send(string) : 데이타 전송
  • close() : 닫기
  • 클라이언트
  •  클래스 socket() : 소켓 객체를 생성
  • 메소드들
  • connect((host, port)) : 접속
  • recv(bufsize) : 데이타 수신
  • send(string) : 데이타 전송
  • close()

Socket 프로그래밍 절차

간단한 Socket 프로그램밍

  • 원도우 Daytime 서비스와 관련 service 명은 [Simple TCP/IP Services] 임
  • 방화벽을 열어 주어야 함.
  • telnet 종료는 : ctrl + ] 이후 quit 명령어 치면 됨.(원도우에서)
  • 소켓의 동작 모드
  • blocking 모드
  • accept, recv, send등을 호출 했을 때, 연결하고자 하는 대상이 없거나 데이터를 즉시 쓸 수 없을 때 처리될 때 까지 대기
  • non-blocking 모드
  • 반대 상황. error 예외 발생
  • 설정
  • setblocking(flag)
  • flag : 0 - nonblocking
  • flag : 1 - blocking
  • 기타 유용한 socket 함수들
  • gethostbyname(), gethostbyname_ex() : 호스트 이름으로 IPv4 포맷으로
  • gethostname() : 호스트 네임 얻기
  • getfqdn() - 전체 도메임 네임 얻기
  • makefile([mode[, bufsize]])
  • 소켓 관련된 파일 객체 생성
  • mode는 파일 오픈할 때의 모드와 동일
  • 사용이 끝났으면 close()함.

ftp 클라이언트

  • ftp 프로토콜
  • 2중 채널 프로토콜
  • Control connection (21)
  • Data connection (20)
  • 기본 포트 21/20
  • 규약 : RFC 959
  • ftplib 모듈
  • 고급 메소드 제공
  • 기본 모드 : Passive (Data 모드에 대한 누가 서버를 하느냐에 따라)
  • 접속 관련
  • class FTP ([host[, user[, passwd [, acct]]]])
  • connect()
  • login()
  • close() or quit()
  • 목록 얻기
  • dir()
  • nlst()
  • 다운로드 / 저장
  • retrlines() : 다운로드
  • retrbinary() : 다운로드
  • storlines() : 저장
  • storbinary() : 저장
  • abort() : 중지
  • 파일 관련
  • size()
  • rename
  • delete
  • 디렉토리 관련
  • pwd()
  • cwd()
  • mkd()
  • rmd()
  • 기타
  • set_pasv
  • sendcmd
  • voidcmd
  • 파이썬으로 작성된 : FtpCube 프로그램

telnet 클라이언트

  • telnetlib 모듈
  • class Telnet
  • open()/ close()
  • Read 관련 메소드들
  • read_until(expected[, timeout])
  • 지정 문자열을 읽을 때 까지 읽는다
  • read_all()
  • 연결이 끊어질 때까지 전체를 읽는다(읽기만 함)
  • read_eager()
  • 당장 읽을 수 있는 문자열을 읽는다
  • expect(list[, timeout])
  • 정규식 중 하나가 매치될 때 까지 읽는다.
  • write(buffer)
  • interact()
  • telnet 클라이언트 에뮬레이터
  • mt_interact()
  • interact()의 multi-thread 버젼

리눅스 방화벽 설정

  • iptables -I INPUT 1 -p tcp --dport 50007 -j ACCEPT

Socket 서버 프로그래밍

  • socketserver 모듈
  • 소켓 서버 클래스
  • 소켓의 유형과 서비스 방법에 따른 객체 생성
  • Request 핸들러 클래스
  • 클라이언트로 부터의 요구를 서비스 해주는 객체 생성
  • 소켓 서버의 유형과 서비스 방법

소켓유형

Domain

AF_INET(IP 소켓)

AF_UNIX(유닉스 소켓)

SOCK_STREAM(TCP)

Synchronous

TCPServer

UnixStreamServer

Forking

ForkingTCPServer

Threading

ThreadingTCPServer

ThreadingUnixStreamServer

SOCK_DGRAM(UDP)

Synchronous

UDPServer

UnixDatagramServer

Forking

ForkingUDPServer

Threading

ThreadingUDPServer

ThreadingUnixDatagramServer

  • 소켓 유형에 따른 Request Handler

소켓 유형

해당 핸들러

SOCK_STREAM(TCP)

StreamRequestHandler

SOCK_DGRAM(UDP)

DatagramRequestHandler

  • 소켓 서버 만들기 절차
  • Request handler 만들기
  • BaseRequestHandler
  • StreamRequestHandler
  • DatagramRequestHandler

class MyRequestHandler(StreamRequestHandler):
   
def handle(self):
   ...

  • 소켓 서버 인스턴스 만들기

server = ThreadingTCPServer(('',PORT), MyRequestHandler)
server.handle_request()  
# 1회 접속 서비스

HTTP 서버 프로그래밍

  • HTTPServer가 하는 일
  • TCP 포트 open , listen
  • 연결이 들어오면 Thread 생성
  • Request 메시지를 읽어들이고 분석
  • 적절한 메소드를 호출해줌
  • 메소드 형식
  • do_<method>()
  • HTTP 서버 모듈
  • BaseHTTPServer
  • 어떠한 명령 메소드도 구현되어 있지 않은 기본 서버
  • 멀티 쓰레드 지원하지 않는다.
  • SimpledHTTPServer
  • GET, HEAD 메소드 구현이 되어 있는 서버
  • CGIHTTPServer
  • SimpledHTTPServer 의 서브 클래스
  • POST 메소드 구현
  • CGI 스크립트 수행

BaseHTTPServer

  • 서버 제작
  • 서버 클래스 : HTTPServer
  • 핸들러 수퍼 클래스 : BaseHTTPRequestHandler
  • 구조
  • BaseHTTPRequestHandler
  • client_address
  • command - 요구 형태(GET, POST, ..)
  • path - 요구 경로
  • headers - 헤더 정보
  • rfile - 입력 스트림
  • wfile - 출력 스트림
  • 요구 형태에 따른 메소드 정의
  • def do_요구형태(self):
  • 헤더 정보 읽어내기
  • for key in self.headers.keys():
       print(key, self.headers[key])
  • 데이터 읽어내기
  • self.rfile.read()
  • 응답 메시지 보내기
  • send_error(code[, message])
  • 완전한 에러메시지 전송
  • send_response(code[, message])
  • 응답 라인, Sever 및 Data 헤더 전송
  • 헤더 전송
  • send_header(keyword, value)
  • end_headers()
  • Body 전송
  • self.wfile.write(...)

SimpleHTTPServer

  • 서버 제작
  • GET, HEAD 요구 형태가 구현되어 있음.
  • 서버 클래스
  • HTTPServer
  • 핸들러 수퍼 클래스
  • SimpleHTTPRequestHandler
  • BaseHTTPRequestHandler의 서브 클래스

CGIHTTPServer

  • 서버 제작
  • SimpleHTTPServer 서브 클래스
  • CGI 프로그램을 수행시키는 기능 추가
  • 서버 클래스
  • HTTPServer
  • 핸들러 수퍼 클래스
  • CGIHTTPRequestHandler
  • SimpleHTTPRequestHandler의 서브 클래스
  • CGI 프로그램의 수행
  • CGI 스크립트 디렉토리에 있는 파일들
  • CGIHTTPServer.CGIHTTPRequestHandler안의 클래스 멤버
  • cgi_directories = [‘/cgi-bin’, ‘/htbin’]

18강 디렉토리와 파일 다루기

파일 목록 얻기

  • glob 모듈
  • os.listdir() : 디렉토리 파일 목록
  • 유닉스 shell 스타일 와일드 카드 문자 사용가능
  • * : 전체 매칭 , ? : 단일문자 매칭
  • [seq] : seq에 있는 임의의 문자 매칭 , [!seq] : 앞과 반대
  • dircache.listdir() : 파일 목록 캐쉬에 저장 (2.x 에서만 지원함.)
  • dircache.annotate() : 2.x에서만 지원

파일 종류 알아 보기

  • os.path.isfile(<파일패스>) - 정규 파일 이면 True 반환
  • os.path.isdir(<파일패스>) - 디렉토리 여부
  • os.path.islink(<파일패스>) - 심볼릭 링크 이면 True 반환
  • os.path.ismount(<파일패스>) - 파일 패스가 마운트 포인트면 True
  • os.path.exist(<파일패스>) - 파일 패스가 존재하면 True 반환

파일 허가권

  • 허가권 알아 보기
  • os.access(<파일패스>, <접근모드>)
  • 접근모드
  • F_OK : 존재
  • R_OK : 읽기
  • W_OK : 쓰기
  • X_OK : 실행
  • 예: os.access(‘t.c’, os.R_OK|os.W_OK)
  • 허가권 변경
  • os.chmod(<파일패스>, <접근모드>)
  • 예 : os.chmod(‘t.c’, 0777)
  • 유닉스(계열)에만 가능

파일 조작

  • 이름 변경
  • os.rename(<A>, <B>)
  • 파일 이동
  • os.rename(<A>, <B>)
  • 파일 복사 (shutil - 여러 복사 함수 제공)
  • shutil.copyfile(<A>, <B>)
  • 파일 삭제
  • os.remove(A)

링크(Unix 계정)

  • 하드 링크
  • os.link(‘t.c’, ‘t.link’)
  • 심볼릭 링크
  • os.symlink(‘t.c’, ‘t.slink’)
  • 심볼릭 링크 정보 얻기
  • os.readlink(‘t.slink’)

파일의 접근 / 수정 시간

  • 읽어오기 (관련 모듈 : os, stat)
  • os.stat(r’/home/cosmoslight/study/a.out’)[stat.ST_ATIME] : 접근 시간
  • os.stat(r’/home/cosmoslight/study/a.out’)[stat.ST_MTIME] : 변경 시간
  • ** r’ --> raw 원시 모드로써 os에서 사용대로 패스를 사용할 수 있도록 함.
  • 설정하기 (관련 모듈 : os, time)
  • os.utime(<파일패스>) : 현재 시간으로 설정
  • os.utime(<파일패스>, (<접근시간>, <수정시간>))

파일 소유자(unix)

  • 소유자 알아보기
  • os.stat(<파일패스>)[stat.ST_UID]
  • 소유자 변경하기
  • os.chown(<파일패스>, <UID> , <GID>)
  • root 사용자만 변경 가능

임시 파일 이름

  • 임시 파일이름 만들기
  • 관련 모듈 (tempfile)

import tempfile
tempfile.mktemp()
tempfile.mktemp(
'.txt')

파일 정보 알아보기

>>> os.stat('t.c')
>>> posix.stat_result(st_mode=
33207, st_ino=805627, st_dev=64768, st_nlink=2, st_uid=501, st_gid=0, st_size=17, st_atime=1513252714, st_mtime=1513252708, st_ctime=1549890685)

필드 이름

설명

ST_MODE

Inode 보호 모드

ST_INO

Inode 번호

ST_DEV

Inode가 있는 장치 번호

ST_NLINK

이 Inode로의 링크 수

ST_UID

소유자의 소유자 ID

ST_GID

소유자의 그룹 ID

ST_SIZE

파일 크기(바이트 수)

ST_ATIME

최근 접근 시간

ST_MTIME

최근 수정 시간

ST_CTIME

최근 상태 변화 시간

디렉토리 다루기

  • 디렉토리 이름 변경
  • os.rename(<old>, <new>)
  • 디렉토리 이동
  • os.rename(<old>, <new>)
  • 디렉토리 복사
  • shutil.copy(src, dst[, symlinks])
  • symlinks - True 이면 심볼릭 링크로 복사
  • symlinks - False 이면 실제 파일 복사
  • 디렉토리 삭제
  • 빈 디렉토리 하나 삭제
  • os.rmdir(<패스>)
  • 다단계 빈 디렉토리 삭제
  • os.removedirs(<level1/leve2>)
  • 전체 디렉토리 삭제 (** 주의 해야 함 )

>>> import shutil
>>> shutil.rmtree('temp')

디렉토리 트리 탐색

  • os.path.walk(<패스>, <콜백함수>, <인수>)
  • 패스 : 시작 디렉토리
  • 콜백함수 : 각 디렉토리에서 호출되는 함수
  • 인수 : 콜백함수로 전달되는 인수
  • 콜백함수(<인수>, <디렉토리명>, <파일명들>)
  • 인수 : walk 함수에서 전달되는 인수
  • 디렉토리명 : 디렉토리 경로
  • 파일명들 : 파일명 목록

# dirwalk.py
import os.path

# 인수, 디렉토리경로명, 파일목록
def dosomething(args, dirname, filenames):

    # .bak로 끝나는 파일명을 fnames에 모은다
   fnames = filter(
lambda fname: fname[-4:] == '.bak', filenames)
   
if len(fnames) > 0:       # .bak로 끝나는 파일이 있으면
       
print dirname, fnames # 디렉토리 경로명과 파일명을 출력한다
# 시작 디렉토리, 호출할 사용자 함수, dosomething의 args로 전달될 인수.
os.path.walk(
"c:\\Python22", dosomething, [])  

경로명 다루기

  • 상대경로를 절대경로로 바꾸기
  • os.path.abspath(‘t.txt’)
  • 사용자명 확장
  • os.path.expanduser(‘~/t.txt’)
  • 파일명 연결
  • os.path.join(‘a’, ‘b’, ‘d.txt’)
  • OS 상관없이 사용할 수 있다. <분리자>.join(<문자열목록>) 사용하지 마라.
  • 파일명 정규화
  • os.path.normcase(<파일명패스>)
  • 경로 정규화
  • os.path.normpath(<패스>)
  • 경로명 다루기
  • 파일명만 추출
  • os.path.basename(<패스>)
  • 디렉토리만 추출
  • os.path.dirname(<패스>)
  • 헤드와 테일로 분리 (디렉토리 와 파일로)
  • os.path.split(<패스>)
  • 드라이브명 추출
  • os.path.splitdrive(<패스>)
  • 확장자 분리
  • os.path.splitext(<패스>)
  • 단 ‘.’도 붙어서 나온다.
  • 변수 확장
  • os.path.expandvars(‘$HOME/t.txt’)
  • 현재/부모 디렉토리 이름 얻기
  • os.curdir # 현재
  • os.pardir # 부모
  • 디렉토리 분리 문자
  • os.sep

파일 이름 패턴 매치

  • fnmatch 모듈 - 주어진 이름과 패턴 일치하는지 검사

>>> import fnmatch
>>> fnmatch.fnmatch('t.txt', '?.txt')
1
>>> fnmatch.fnmatch('a.txt', '[abc].txt')
1

19강 - 프로세스 다루기

프로세스 관련 정보 얻기

  • 현재 작업 디렉토리
  • os.getcwd()
  • 환경 변수 다루기 (읽기/쓰기)
  • os.environ[<변수명>]
  • 프로세스 ID
  • os.getpid() - 현재 프로세스 ID
  • os.getppid() - 부모 프로세스 ID
  • 프로세스 사용자/그룹 ID
  • os.getuid(), os.getgid()
  • os.geteuid(), os.getegid()

다른 프로그램 실행시키기

  • os.system(<명령어>) - unix, win
  • subshell에서 command를 실행
  • 출력 정보를 받을 수 없음.
  • os.startfile(<패스>)
  • 패스에 해당하는 파일과 관련된 프로그램을 실행한다.
  • os.spawnXX(mode, …)
  • mode : os.P_WAIT, os_NOWAIT
  • os.P_WAIT : 실행 후 대기
  • os.P_NOWAIT : 실행 후 계속 진행

프로세스 실행시키고 파이프로 대화하기

  • 단방향 파이프
  • popen(<명령어>[, <모드>[, <버퍼크기>]])

>>> f = os.popen('dir', 'r')
>>> s = f.read() # 전체 데이터를 읽는다

  • 양방향 파이프
  • popen2(<명령어>[, <모드>[, <버퍼크기>]])
  • 반환값 : (child_stdin, child_stdout)
  • 단점 :
  • 쓰기나 읽기가 종료 된후 다른 파이프 통신이 가능함.
  • 읽기 쓰기를 번갈아 할수 없음
  • 위를 대안 하는 모듈 : pexpect (유닉스용)

>>> w, r = os.popen2('sort')
>>> w.write('aaa\n')
>>> w.write('zzz\n')
>>> w.close()       # 쓰기를 종료 한다.
>>> print(r.read()) # 읽어낸다. 정렬이 되어서 나온다.

프로세스 복제/생성

  • os.fork() - unix
  • 자식 프로세스는 0, 부모 프로세스는 자식 pid 리턴
  • execl(path, arg0, arg1, …) - unix, win
  • 현재의 프로세스를 새로운 path프로그램으로 대치
  • return 없음
  • wait() - unix
  • 자식 프로세스의 종료를 대기함.
  • 리턴 : (pid, exit_status)
  • exit_status : exit_status(8bit) + signale_no(8bit)

고아/좀비/데몬

  • 고아(orphan) 프로세스
  • 리턴값을 받아줄 부모가 먼저 종료한 프로세스. init 프로세스의 양자가 된다.
  • 좀비(zombie) 프로세스
  • 자신의 종료코드 값이 부모에 의해 받아들여질때까지 대기하는 종료 프로세스
  • 데몬(daemon) 프로세스
  • 시스템에 남아서 필요할 때 요구된 작업을 수행하는 백그라운드 프로세스

멀티 쓰레딩

  • Thread특징
  • Light weight process
  • stack을 별도로 갖는다
  • 정적인 공유 메모리(전역변수 공간)을 갖는다.

thread 모듈

  • 새로운 쓰레드의 시작
  • start_new_thread(<function>, <args>[, <kwargs>])
  • 종료하기
  • return - 함수 종료시
  • exit()
  • 상호 배제
  • 락 객체 얻기
  • allocate_lock() 함수
  • 잠그기
  • <락객체>.acquire()
  • <락객체>.release()
  • 쓰레드 종료 판단하기
  • 예제 소스 참고

threading 모듈

  • 고차원적이고 풍부한 기능 지원
  • 클래스 지원
  • concurrent processing을 위한 다양한 객체 지원
  • 쓰레드 호출 방법
  • 호출 가능한 객체(함수등)을 생성자에 직접 전달하는 방법 (예제: threadex6.py)
  • 서브 클래스에서 run메소드를 중복하는 방법(예제: threadex7.py)
  • Lock, RLock 객체
  • 상호배제에 활용
  • Condition 객체
  • 모니터에서 사용하는 조건 변수
  • Semaphore 객체
  • 유명한 세마포
  • Event 객체
  • 동기화에 유용

Queue for multi-thread

  • Queue 모듈의 Queue 클래스
  • class Queue([maxsize]) - 0 이면 무한대
  • put(item[,block]) - block (True) 이면 잠금
  • get([block])
  • 질의 메소드 : 멀티쓰레드 환경에 신로 할수 없음.
  • qsize()
  • empty()
  • full()
  • 생산자 소비자 문제 해결 예
  • threadex12.py 참고

**번외

  • 생산자 - 소비자 문제
  • **복습 (고아/좀비/데몬)
  • defunct -

20강 - 정규식

개요

  • 다양 정보 유형을 가진 문자열에서 필요한 정보 유형만을 추출하기 위한 방법
  • 문자열 패턴의 검색, 추출, 대치 규칙을 정의
  • 파이썬 정규식 모듈 - re

메타문자

  • 정의 - 문자 자체보다 문자패턴을 기술하기 위한 제어문자
  • 반복 메타 문자

반복

메타 문자

의미

*

0회 이상 반복

ca*t는ct, cat, caat, caaaaaat등과매치

+

1회 이상 반복

ca+t는cat, caaaaaat등과매치된다.

?

0회 혹은 1회

ca?t는ct, cat와매치된다.

{m}

m회 반복

ca{2}는caa와매치된다.

{m,n}

m회 부터 n회 까지 반복

ca{2,4}는caat, caaat, caaaat와매치된다.

  • 매칭 메타 문자

메타문자

의미

.

줄바꿈 문자를 제외한 모두 문자와 매치

re.DOTALL 모드로 사용하면 줄 바꿈 문자도 매치된다

^

  • 문자열의 시작과 매치된다
  • re.MULTLINE 모드에서는 각 행의 시작과 매치된다.
  • [] 메타기호  안에서는 반대의 문자열을 취한다. [^5]는 5가 아닌 문자이다.

$

  • 문자열의 끝과 매치된다
  • []메타기호 안에서는 메타기호로 사용되지 않고 순수한 $문자로 매치됨

[]

선택적 문자 집합을 나타냄

[abc]는 ‘a’,’b’,’c’중 한 문자를 의미한다. [a-c]와 같이 쓸수도 있다.

|

a|b는 a 또는 b 의 의미

()

정규식을 그룹으로 묶는다.

이스케이프 기호

기호

의미

\\

역슬래쉬 문자 자체를 의미한다.

\d

모든 숫자와 매치된다 [0-9]

\D

숫자가 아닌 문자와 매치된다. [^0-9]

\s

화이트스페이스 문자와 매치된다. [ \t\n\r\f\v]

\S

화이트스페이스 문자가 아닌 것과 매치된다. [^ \t\n\r\f\v]

\w

숫자 또는 문자와 매치된다. [a-zA-Z0-9_]

\W

숫자 또는 문자와 아닌 것과 매치된다 [^a-zA-Z0-9_]

\b

단어의 경계를 나타냄. 단어는 영문자 혹은 숫자의 연속 문자열로 가정한다. **공부 필요

\B

\b의 반대로 단어의 경계가 아님을 나타냄.

match

  • 문자열 매치 하기
  • 문자열 시작부터 매치
  • Match = match(<패턴>, <문자열>[, 플래그])
  • 반환값 매치된경우 Match 객체 아니면 None

>>> m = re.match('[0-9]', '1234') # 단일 숫자
>>> m.group()
'1'
>>> m = re.match('[0-9]+', '1234   ') #1개의 이상의 숫자 및 뒤에 공백이 오는 경우
>>> m.group()
'1234'
>>> re.match('[0-9]+', ' 1234 ') # 앞에공백. 매치실패
>>> re.match(r'[ \t]*[0-9]+', ' 123') # 공백매치추가
<_sre.SRE_Match object at
0x00AEEA60>
>>> m = re.match('\s*\d+', ' 123')
>>> m.group()
' 123'
>>> m = re.match('\s*(\d+)', ' 1234 ')
>>> m.group(1) # 첫번째괄호내의문자열
'1234'

search

  • 부분적인 문자열 매치
  • 형식 : search(<패턴>, <문자열>[, 플래그])

>>> re.search('\d+', ' 1034 ').group()
'1034'
>>> re.search('\d+', ' asf123 ').group()
'123'

정규식

  • raw모드로 정규식을 표현하기

>>> '\d'
'\\d'
>>> '\b' # 백스페이스로표현된다
'\x08'
>>> '\\b' # 이중으로\를추가해야한다
'\\b'
>>> r'\b'# raw 문자열
'\\b'
>>> '\\'# \문자하나를표현
'\\'
>>> r'\\' # \문자두개
'\\\\'
# 하나의\를매치하기위해\네개를써야한다
>>> re.search('\\\\', ' \').group()
'
\\'
>>> re.search(r'
\\', ' \').group()
'
\\'
>>> re.search('
\d+', ' !123! ').group()
'
123'
>>> re.search('
\d+', ' abc123 ').group()
'
123'
>>> re.search('
\b\d+\b', ' !123! ')
>>> re.search('
\b\d+\b', ' abc123 ')
>>> re.search('
\\b\d+\\b', ' !123! ').group()
'
123'
>>> re.search('
\\b\d+\\b', ' abc123 ')

  • 탐욕적(greedy) 매칭
  • 가능한 한 최대한 많이 매칭하는 것
  • 최소(non-greedy) 매칭

기호

의미

*?

*와 같으나 문자열을 최소로 매치한다

+?

+와 같으나 문자열을 최소로 매치한다

??

?와 같으나 문자열을 최소로 매치한다

{m,n}?

{m,n}과 같으나 문자열을 최소로 매치한다

  • 예제

>>> s = '<a href="index.html">HERE</a><font size="10">'
>>> re.search(r'href="(.*)"', s).group(1) # greedy
'index.html">HERE</a><font size="10'
>>> re.search(r'href="(.*?)"', s).group(1)
'index.html'

문자열 추출

  • 매치된 문자열 추출하기
  • match 객체 메소드
  • group() : 매치된 문자열들을 리턴한다
  • start() : 매치된 문자열의 시작 위치를 리턴한다 (index 형태)
  • end() : 매치된 문자열의 끝 위치를 리턴한다(index 형태)
  • span() : 매치된 문자열의 (시작, 끝) 위치를 튜플을 반환 한다.
  • match 객체의 group 관련 메쏘드
  • group() : 매치된 전체 문자열을 반환함.
  • group(n) : n 번째 그룹 문자열을 리턴함. 0은 매치된 전체 문자열
  • groups() : 매치된 전체 그룹 문자열을 튜플 형식으로 반환한다.
  • groups() 예제

>>> m = re.match(r'(\d+)(\w+)(\d+)', '123abc456')
>>> m.group()
'123abc456'
>>> m.group(0)
'123abc456'
>>> m.group(1)
'123'
>>> m.group(2)
'abc45'
>>> m.group(3)
'6'
>>> m.groups()
(
'123', 'abc45', '6')
>>> m.start()
0
>>> m.end()
9
>>> m.span()
(
0, 9)
>>> m = re.match('(a(b(c))(d))', 'abcd')
>>> m.group(0)
'abcd'
>>> m.group(1)
'abcd'
>>> m.group(2)
'bc'
>>> m.group(3)
'c'
>>> m.group(4)
'd'

그룹 이름

  • 그룹에 이름 사용하기
  • 사용패턴 : (?P<이름>...)
  • 이름 : 그룹이름,
  • … : 일반 정규식
  • 예제

>>> m = re.match(r'(?P<var>[_a-zA-Z]\w*)\s*=\s*(?P<num>\d+)', 'a = 123')
>>> m.group('var')
'a'
>>> m.group('num')
'123'
>>> m.group()
'a = 123'

모듈 re의 주요 함수

메소드

설명

compile(pattern[, flags])

pattern을 컴파일 하여 정규식 객체를 리턴한다.

search(pattern, string[, flags])

string을 검사해서 pattern에 맞는 문자열 부분이 있는가 찾는다.

match(pattern, string[, flags])

string을 시작부터 pattern에 맞는 문자열을 찾는다.

split(pattern, string[, maxsplit=0])

string을 pattern을 기준으로 분리한다

findall(pattern, string)

string에서 pattern을 만족하는 모든 문자열을 추출함

sub(pattern, repl, string,[, count=0])

string에서 pattern을 repl로 대치한다.

subn(pattern, repl, string,[, count=0])

sub와 동일하나 대치횟수도 함께 전달된다.

escape(string)

영문자 숫자가 아닌 문자들을 백슬러쉬 처리해서 리턴한다 임의의 문자열을 정규식 패턴으로 사용할 경우에 유용하다.

  • re.split(pattern, string[, maxsplit=0])

>>> re.split('\W+', 'applt, orange and spam.') # 영문자,숫자,언더라인이외의1개이상의문자를기준으로분리한다
[
'applt', 'orange', 'and', 'spam', '']
>>> re.split('(\W+)', 'applt, orange and spam.') # 패턴에괄호가있으면괄호에포함된문자열도함께포함된다.
[
'applt', ', ', 'orange', ' ', 'and', ' ', 'spam', '.', '']
>>> re.split('\W+', 'applt, orange and spam.', 1) # maxsplit인수가주어졌을경우최대분리횟수를나타낸다.
[
'applt', 'orange and spam.']
>>> re.split('\W+', 'applt, orange and spam.', 2)
[
'applt', 'orange', 'and spam.']
>>> re.split('\W+', 'applt, orange and spam.', 3)
[
'applt', 'orange', 'and', 'spam.']

  • findall(pattern, string)

>>> re.findall(r'[_a-zA-Z]\w*', '123 abc123 def')
[
'abc', 'def']
>>> s = '''
<a href="link1.html">link1</a>
<a href="link2.html">link2</a>
<a href="link3.html">link3</a>'''

>>> re.findall(r'href="(.*?)"', s)
[
'link1.html', 'link2.html', 'link3.html']

정규식 객체 사용하기

  • compile(pattern[, flags])
  • 정규식을 컴파일해서 정규식 객체르 반환
  • 정규식의 반복적 적용에 유용
  • 정규식에 플래그 함께 사용가능
  • 예제

>>> p = re.compile(r'([_a-zA-Z]\w*)\s*=\s*(\d+)')
>>> m = p.match('a = 123')
>>> m.groups()
(
'a', '123')
>>> m.group(1)
'a'
>>> m.group(2)
'123'

  • compile 함수에 사용 가능한 플래그

플래그

설명

I, IGNORECASE

대소문자를 구별하지 않고 매치

L, LOCALE

\w, \W, \b, \B를 현재의 로케일에 영향을 받는다

M, MULTILINE

^가 문자열의 맨 처음, 각 라인의 맨 처음과 매치됨.

$는 문자열의 맨 끝, 그리고 각 라인의 끝에 매치됨.

기본 값은 ^는 문자열의 맨 처음만, $는 문자열의 맨 마지막만 매치됨.

S, DOTALL

.를 줄바꾸기 문자(\n)도 포함하여 매치하게 된다.

U, UNICODE

\w, \W, \b, \B가 유니코드 문자에 맞게 처리된다

X, VERBOSE

보기 좋은 정규식을 쓸 수 있게 해준다

정규식 안의 공백은 무시된다.

공백을 사용하려면 백슬러쉬 문자로 표현해야 한다.

정규식 안에 #문자를 쓰면 그 주석으로 그 이후의 모든 문자는 무시된다.

  • 예제

>>> import re
>>> p = re.compile('the', re.I)
>>> p.findall('The cat was hungry. They were scared because of the cat')
[
'The', 'The', 'the']

  • 주요메소드

메소드

설명

search(string[, pos[, endpos]])

string을 검사해서 문자열 부분을 차즌다. pos, endpos는 string의 찾을 문자열의 범위를 지정한다.

match(string[, pos[, endpos]])

search와 동일하나 처음부터 찾는다.

split(string[, maxsplit = 0])

re.split 와 동일

findall(string)

re.findall 와 동일

sub(repl, string[, count=0])

re.sub 와 동일

subn(repl, string[, count=0])

re.subn 와 동일

  • 예제

>>> t = 'My ham, my egg, my spam'
>>> p = re.compile('(my)', re.I)
>>> pos = 0
>>> while 1:
       m = p.search(t, pos)
       
if m:
           
print m.group(1)
           pos = m.end()
       
else: break
My
my
my

문자열 대치

  • sub(repl, string[, count=0])
  • count를 설정하면 대치 횟수 조절 가능
  • 예제

>>> re.sub(r'[.,:;]', '', 'a:b;c, d.') # 특수문자없애기
'abcd'
>>> re.sub(r'\W', '', 'a:b;c, d.') # 영문자, 숫자,
                                 
# 언더라인만제외하고모두없애기
'abcd'

  • 대치할 문자열에 매치된 문자열 다시 사용하기 (이해 하**)
  • {\n}, {g\<n>} : 그룹 n의 문자열로 대치 한다.

>>> p = re.compile('section{ ( [^}]* ) }', re.VERBOSE)
# VERBOSE를쓴것은공백을무시하기위해서이다.
>>> p.sub(r'subsection{\1}','section{First} section{second}')
'subsection{First} subsection{second}'
# name 키워드를 사용하여
>>> p = re.compile('section{ (?P<name> [^}]* ) }', re.VERBOSE)
>>> p.sub(r'subsection{\g<name>}','section{First}')
'subsection{First}'

  • 대치 문자열을 함수로 처리하기(sub의 첫 인수로 대치 함수 지정)

>>> def hexrepl( match ):
       value = int( match.group() )
       
return hex(value)
>>> p = re.compile(r'\d+')
>>> p.sub(hexrepl, 'Call 65490 for printing, 49152 for user code.')
'Call 0xffd2 for printing, 0xc000 for user code.'

  • 주민번호 추출

>>> p = re.compile('(\d{6})-?(\d{7})')
>>> p.search('123456-1234567').groups()
(
'123456', '1234567')
>>> p.search('1234561234567').groups()
(
'123456', '1234567')

  • HTML에서 URL 추출

import re
s =
'''<a href="http://www.daum.net">daum</a>
<a href='http://www.naver.com'>naver</a>
<a href=http://www.chosun.com>chosun</a>
<a href=http://www.chosun.com class>chosun</a>
<a href="http://job.daum.net/ " target="new">
<a href="http://go.daum.net/bin/go.cgi?relative=1&url=/Mail-bin/login_f.cgi%3Ferror%3Dlogin" class="tls0">
'''

p = re.compile(
'''href=([^'"]\S+?)[\s>]|
      href="([^"]*?)"|
      href='([^']*?)\'''', re.I | re.X)
pos = 0
while 1:
    match = p.search(s, pos)
    if match:
        url= match.groups()
        pos = match.end()
        print filter(None, url)[0]
    else:
        break

**번외

  • ()그룹에 대해서 좀더 고민 해 보자

21강 XML 처리하기

개요

  • Python으로 제공하는 툴
  • Standard Library
  • PyXML
  • 4Suite
  • PCDATA : Parsed Character Data
  • CDATA : character Data

대표적인 파이썬 XML 도구 (현재 3.X에서는 다름.)

  • 파이썬 표준 라이브러리
  • 기본 기능을 제공
  • xml.sax
  • Non-validating SAX parser(xml.parser.expat)
  • xml.dom.minidom
  • PyXML (2.x에서만 제공)
  • 공식 사이트
  • 참고 사이트
  • 한글 링크#1 - 한빛미디어 제공
  • SAX 여러 파서 제공
  • DOM레벨 2 대부분 구현
  • 4XPath : xml.xpath
  • 4XSLT : xml.xslt
  • 4Sutie

XML 문서 처리 방법

  • SAX : Simple API for XML
  • 이벤트 기반으로 콜백 함수 호출
  • 빠름, 한쪽 방향으로만 진행
  • 메모리 사용이 적음
  • 구조적 변화 줄 수 없음.
  • DOM : Document Object Model
  • 객체 트리 생성
  • 메모리 부담 가능
  • 처리시간 더 필요
  • 전체문서 관점 제공
  • 임의의 노드로 이동
  • 트리 수정 변경 가능

핸들러 만들고 파싱하기

  • Handler
  • xml 문서 파싱중에 발생하는 여러가지 이벤트를 처리할 객체

SAX 핸들러

  • ContentHandler 객체
  • setContentHandler()로 등록
  • DTDHandler 객체
  • setDTDHandler()로 등록
  • EntityResolver 객체
  • 별도 사용하지 않음.
  • setEntityResolver()로 등록
  • ErrorHandler 객체
  • setErrorHandler()로 등록

이름 공간 모드인 경우의 예

  • 이름 공간 사용 설정

>>> from xml.sax.handler import feature_namespaces
>>> parser = make_parser() # 파서 객체를 만들고
>>> parser.setFeature(feature_namespaces, 1)

검증 파서 (validation parser)

  • 에러 핸들을 등록하는 것이 좋다.
  • 처리 중단시키려면 SAXParseException 예외 발생
  • 검증파서 만들기1

>>> from xml.sax.sax2exts import XMLValParserFactory
>>> parser = XMLValParserFactory.make_parser()

  • 검증파서 만들기2

>>> from xml.sax.import make_parser, handler
>>> parser = make_parser(['xml.sax.drivers2.drv_xmlproc'])
>>> parser.setFeature(handler.feature_validation, 1)

SAX 한글 처리

  • XML 기본 인코딩
  • UTF-8
  • 대부분의 한글 코드
  • euc-kr
  • 처리 방법
  • 일괄 코드 변환 (euc-kr -> utf-8)
  • 파일을 읽어들이고 utf-8로 변환
  • 문자열 코드 변환 방법
  • euc-kr -> 유니코드
  • u = unicode(s, ‘euc-kr’)
  • 유니코드 -> euc-kr
  • s = s.encode(‘euc-kr’)

DOM

  • DOM : Document Object Model
  • W3C에서 만드는 플랫폼과 언어에 독립적인 API
  • 객체지향적 API
  • 다양한 binding 존재(Python, Java, C++, VB..)
  • 레벨1 -> 레벨2 -> 레벨3
  • 표준 규격 사이트 (링크)

파이썬 DOM 모듈

  • 표준 라이브러리
  • minidom
  • pulldom
  • PyXML
  • 4DOM, javadom(Jython)
  • 2.4까지만 지원함.
  • 4Suite
  • 다른 API
  • lxml

Load and Save

  • DOM Core 레벨 2까지는 Load and Save 기능 지원하지 않으므로 binding 마다 입출력 방법이 다르다.

DOM 트리 구조

  • sample02.xml

<?xml version="1.0" ?>
<userlist>
 
<user sex="male">
     
<name>gslee</name>
     
<email>gslee@mail.kw.ac.kr</email>
 
</user>
 
<user sex="female">
     
<name>spam</name>
     
<email>spam@mail.kw.ac.kr</email>
 
</user>
</userlist>

  • 위의 문서를 dom 트리 구조로 표현 된 모습(주의 \n 존재한다.)

노드 탐색

  • 노드 타입 확인하기
  • nodeType 값 (DOM에서 정의된 값, 링크)

ELEMENT_NODE                 = 1
ATTRIBUTE_NODE               = 2
TEXT_NODE                    = 3
CDATA_SECTION_NODE           = 4
ENTITY_REFERENCE_NODE        = 5
ENTITY_NODE                  = 6
PROCESSING_INSTRUCTION_NODE  = 7
COMMENT_NODE                 = 8
DOCUMENT_NODE                = 9
DOCUMENT_TYPE_NODE           = 10
DOCUMENT_FRAGMENT_NODE       = 11
NOTATION_NODE                = 12

  • >>> dom.nodeType == dom.DOCUMENT_NODE

노드 이동 멤버 메쏘드

노드의 종류와 계층 구조

Node IDL (interface definition language)

엘리먼트 노드 탐색하기

  • getElementsByTagName(tagName)
  • tagName을 갖는 엘리먼트 노드 리스트 리턴
  • getElementsByTagNameNS getElementsByTagNameNS(namespaceURI, localName)
  • 이름 공간의 기준

속성 참조

  • getAttribute(attrName attrName)
  • 정의된 속성이 없다면 공문자열 리턴
  • getAttributeNS(NmSpace, attrName)
  • attributes 멤버는 사전 인터페이스의 NameNodeMap 객체를 리턴

DOM Core - 노드 생성 메소드

메소드

설명

createElement(tagname)

새로운 엘리먼트 노드를 생성한다.

createElementNS(namespaceURI, qualifiedName)

createElement 이름 공간 버젼

createTextNode(data)

새로운 텍스트 노드를 만든다

createComment(data)

주석 노드를 만든다

createDocumentFragment()

DocumentFragment 객체를 생성한다

createCDATASection(data)

CDATA 섹션을 만든다.

createEntityReference(name)

Entity 참조를 생성

createProcessingInstruction(target, data)

주어진 이름과 데이터로 ProcessInstruction 노드를 만든다

노드 추가,삭제, 복사 메쏘드

메소드

설명

appendChild(newChild)

새로운 자식 노드를 자식 노드 리스트의 마지막에 추가하고 newChild를 반환 한다.

insertBefore(newChild, refChild)

새 자식노드를 지정한 노드(refChild) 앞에 삽입하고 newChild를 반환 한다.

removeChild(oldChild)

자식노드를 삭제한다. oldChild는 현재 노드의 자식 노드이어야 함.

replaceChild(newChild, oldChild)

기존의 노드를 새 노드로 교환함. oldChild는 현재 노드의 자식이어야 함.

cloneNode(deep)

현재의 노드를 복제함. deep가 True이면 모든 자식 노드도 복제 함. 복제된 노드를 반환함

normalize()

인접한 텍스트 노드들을 하나로 결합한다. 트리를 단순화하여 텍스트 처리 효율 높힘.

DOM Core 관련 정리

  • 문서 생성
  • DOMImplementation 인터페이스를 이용하여 문서 객체 생성
  • createDocument(namespaceURI, qualifiedName, docType)
  • 텍스트 변경
  • 텍스트 노드의 data 멤버를 이용
  • 속성 추가/변경
  • setAttributeNS()
  • 속성 삭제
  • removeAttributeNS()
  • 노드 임포트 하기
  • 다른 Document에서 노드 임포트
  • importNode(importedNode, deep)

DOM Traversal 인터페이스 (지원되지 않는다. minidom 에서)

  • DOM 레벨 2 인터페이스
  • 지원 인터페이스
  • NodeIterator : 1차원 적으로 노드 접근
  • TreeWalker : 트리 방식으로 노드 접근
  • NodeFilter : 접근할 노드를 필터링

Node Iterator

  • 객체 생성 메소드
  • createNodeIterator(root, whatToShow, filter, entityReferenceExpansion)
  • whatToShow - 뭘 보여 줄지 결정 ,예) NodeFilter.SHOW_ELEMENT
  • filter
  • 반복자 메쏘드
  • nextNode()
  • previousNode()
  • detach() : 반복자 사용 종료

Node Filter

  • 임포트 : from xml.dom.NodeFilter import NodeFilter
  • 필터 상수의 사용
  • 필터 상수 목록(NodeFilter)
  • SHOW_ALL
  • SHOW_ELEMENT
  • SHOW_ATTRIBUTE
  • SHOW_TEXT
  • SHOW_CDATA_SECTION
  • SHOW_ENTITY_REFERENCE
  • SHOW_ENTITY
  • SHOW_PROCESSING_INSTRUCTION
  • SHOW_COMMENT
  • SHOW_DOCUMENT
  • SHOW_DOCUMENT_TYPE
  • SHOW_DOCUMENT_FRAGMENT
  • SHOW_NOTATION
  • 설계
  • NodeFilter 인터페이스 상속
  • acceptNode 메쏘드 재정의
  • 전달되는 노드를 취하려면 FILTER_ACCEPT
  • 버리려면 FILTER_REJECT 반환

XPath - 개요

  • 절차적인 언어 x
  • 노드 검색을 위한 기능으로만 사용됨.

결과 자료형

  • XPath 처리 결과 자료형
  • 노드 집합(node set)
  • 문자열 : unicode string
  • 숫자 : floating point number
  • 부울값 : true or false

Context(문맥)

  • Context
  • XPath 식이 적용되고 있는 노드
  • XSLT, XPointer에 자주 적용됨.
  • Context 구성 요소
  • Context node - 현재 작업 노드
  • Context size - 전체 문맥 노드의 수
  • Context position - 현재 문맥 노드의 위치
  • Variable bindings - 어떤 값에 연결된 변수의 집합
  • Defined namespaces - 영역 안에 정의된 이름 공간 정의 집합

Location path : 위치 경로

  • 가장 일반적으로 사용되는 XPath 표현식
  • 마치 디렉토리나 파일 경로지정과 유사
  • 다양한 조건의 테스트에 의한 경로 지정이 가능
  • 여러노드가 지정될 수 있다.

Path expression(경로 표현식)

  • / or // 로 분리된 단계 표현식(step expression)의 연결
  • 첫 ‘/’는 root node를 의미
  • ‘//’는 문맥 node 혹은 자손 node를 의미
  • 단계(step) 표현식
  • ForwardAxis::NodeTest
  • ReverseAxis::NodeTest
  • AbbreviatedForwardStep
  • AbbreviatedReverseStep

Axes : 문맥에서 진행방향을 결정

  • ForwardAxis
  • child
  • descendant
  • attribute
  • self
  • descendant-or-self
  • following-sibling
  • following
  • namespace
  • ReverseAxis
  • parent
  • ancestor
  • preceding-sibling
  • preceding
  • ancestor-of-self

Node test

  • axes의 노드를 줄이는데 사용
  • 이름 테스트
  • 노드 이름을 데스트 혹은 ‘*’
  • 종류 테스트
  • processing-instruction()
  • comment()
  • text()
  • node()

Axes::NodeTest - 예제

  • descendant::email
  • ancestor::*
  • preceding preceding-sibling::processing processing-instruction()
  • attribute::*
  • following following-sibling::*/descendant::name/child::text()
  • child::ADDRBOOK/child::ENTRY/child::PHONENUM/child::text()

Abbreviations(축약)

표현식

축약형

child::

생략

attribute::

@

self::

.

parent::

..

/descendant-or-self::node()

//

  • following-sibling::*/descendant::PHONENUM/text()
  • 축약 : ADDRESSBOOK/ENTRY/PHONENUM/text()

Predicates(술부)

  • [..]로 표현되는 식
  • 부울값 혹은 숫자를 리턴하는 표현식
  • 부울값인 경우 참인 노드만 취한다
  • 숫자인 경우, 지정된 위치의 노드만이 취해짐
  • child::user[attribute::sex=“male”]/child::email[1]
    혹은
    user[@sex=“male”]/email[1]

XPath 표현식 예제

  • 'user/name'
  • 'user/name/text()'
  • 'user[2]/name/text()'
  • 'user[@sex="male"]'
  • '//email'
  • '/ userlist userlist//email'
  • 'user/email/../name'

기본 연산자

  • 산술 연산자
  • +, -, *, , div, idiv idiv, mod
  • 비교 연산자
  • <, >, <=, >=, =, !=
  • lt lt, , gt gt, le, , ge ge, , eq eq, , ne
  • 노드 비교
  • is, isnot
  • //book[ isbn isbn=“1234 1234”] is //book[call= ] call=“q. abc 890 890”]
  • 논리 연산자
  • and, or
  • 순서 비교 연산자
  • <<, >>

함수

함수

설명

position()

현재 문맥 위치 리턴

last()

문맥 크기/ 마지막 문맥 노드 리턴

count(<node set>)

<node set>의 노드의 수 리턴

local-name(<node set>)

첫 노드의 지역 이름을 리턴

concat(<string>, .. , <string>)

문자열 연결하여 반환

contains(<string>, <string>)

첫번째 문자열에 두번째 문자열이 포함여부

not(<boolena>)

참과 거짓을 반대로

sum(<node-set>)

각 노드를 숫자로 변환하여 합을 계산

  • 예) user[last()]/email[contains(., ‘pymail’)]

XSLT

  • Extensible Stylesheet Language Transformations
  • XML 문서를 다른 포맷으로 변환하는데 사용하는 언어
  • XML -> XML
  • XML -> HTML
  • XML -> Text
  • 규약
  • 사용 패키지
  • PyXML -> 현재 미지원
  • 4Suite -> 현재 미지원
  • ** 관련 라이브러리 찾아야 한다.
  • 참고 사이트들
  • XSLT 처리 모델
  • 소스트리 : 변환될 원래문서. 임의의 XML 문서
  • 스타일시트 트리 : 변환 지시 내용을 담고 있는 트리. XSLT 규약을 만족하는 트리
  • 결과트리 : 변환된 트리(XML, HTML, Text)

stylesheet

  • 스타일시트 루트
  • <? xml version=”1.0” ?>

<xsl stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Tranform" version="1.0">
</xsl:stylesheet>

  • output 엘리멘트
  • <xsl:output method=”html” indent=”yes”/>
  • template

<xsl:template match="/">
 
<html>
     
<head><title>User List</title></head>
     
<body>
       
<h1>User List</h1>
       
<table border="1">
         
<tr>
           
<th>sex</th>
           
<th>name</th>
           
<th>email</th>
         
</tr>
         
<xsl:apply-templates/>
       
</table>
     
</body>
 
</html>
</xsl:template>


<xsl:template match="user">
 
<tr>
   
<td><xsl:value-of select='@sex'/></td>
   
<xsl:apply-template select="name|email"/>
 
</tr>
</xsl:template>

<xsl:template match="name">
 
<td><xsl:apply-template/></td>
</xsl:template>

22강 : XML-RPC 사용하기

개요

  • Procedure Call
  • 한 컴퓨터 내에서 프로시져를 호출하고 수행
  • RPC(Remote Procedure Call)
  • 네트워크를 통해 있는 다른 컴퓨터의 프로시저를 호출
  • 연결 지연 및 전송 지연등의 부담에도 불구하고 분산 처리 및 정보의 공유를 가능하게 함
  • XML : 문서 교환의 표준 포맷
  • XML-RPC
  • HTTP 기반의 XML문서 형식의 RPC
  • HTTP와 XML이 이미 네트워크과 문서교환의 표준이므로 이 기종간의 컴퓨터/ 다른 언어와 쉅게 연결이 됨
  • 즉, 언어와 컴퓨터의 장벽을 없앰.
  • ** 추가 공부 : 과연 많이 사용되고 있는가

XML-RPC Protocol

Request 형식

  • 예제

POST/RPC2 HTTP/1.0
User-Agent: Frontier/5.1.2 (WinNT)
Host: betty.userland.com
Content-Type: text/xml
Content-length: 181
<?xml version="1.0"?>
<methodCall>
 
<methodName>examples.getStateName</methodName>
        
<params>
                
<param>
                        
<value><i4>41</i4></value>
                
</param>
        
</params>
</methodCall>

  • 헤더 형식
  • Method : POST
  • User Agent, Host 필수
  • Content-Type : text/html
  • XML Payload

  • value 형식 (단순 데이터)

태그

자료형

예제

<i4> or <int>

4바이트 부호있는 정수

-12

<boolean>

True, False

1

<string>

ASCII 문자열, 한글 가능

hello world

<double>

배정도 실수형

-12.214

<dateTime.iso8601>

날짜와 시간

19980717T14:08:55

<base64>

Base64 인코딩된 이진 데이터

eW91IGNhbid0IHJlYWQgdGhpcyE=

  • 복합데이터 (<struct>)
  • 재귀적 표현도 가능

<struct>
 
<member>
     
<name>lowerBound</name>
     
<value><i4>18</i4></value>
 
</member>
 
<member>
     
<name>upperBound</name>
     
<value><i4>139</i4></value>
 
</member>
</struct>

  • 배열데이터(<array>)
  • 재귀적 표현도 가능

<array>
        
<data>
                
<value><i4>12</i4></value>
                
<value><string>Egypt</string></value>
                
<value><boolean>0</boolean></value>
                
<value><i4>-31</i4></value>
        
</data>
</array>

Response 형식

  • 예제

HTTP/1.1 200 OK
Connection: close
Content-Length: 158
Content-Type: text/xml
Date: Fri, 17 Jul 1998 19:55:08 GMT
Server:UserLandFrontier/5.1.2-WinNT
<?xml version="1.0"?>
<methodResponse>
   
<params>
       
<param>
           
<value><string>South Dakota</string></value>
       
</param>
   
</params>
</methodResponse>

  • 형식

  • 에러가 발생한 경우

  • 형식

HTTP/1.1 200 OK
Connection: close
Content-Length: 426
Content-Type: text/xml
Date: Fri, 17 Jul 1998 19:55:02 GMT
Server:UserLandFrontier/5.1.2-WinNT
<?xml version="1.0"?>
<methodResponse>
 
<fault>
   
<value>
     
<struct>
       
<member>
         
<name>faultCode</name>
         
<value><int>4</int></value>
       
</member>
       
<member>
         
<name>faultString</name>
         
<value><string>Too many parameters.</string></value>
       
</member>
     
</struct>
   
</value>
 
</fault>
</methodResponse>

XML-RPC DTD

25강 - C확장 모듈과 확장 형 만들기

(파이썬 2.x에서만 아래 코드로됨) 3.x에 대해서 추가 공부로 필요함.

개요

  • C확장 모듈/형을 왜 만드나
  • 처리 시간의 향상
  • 코드의 은닉
  • 다른 C 라이브러리 사용을 위한 Wrapper 코드 제작
  • 대표적 모듈
  • 프로토타이핑(prototyping)
  • 파이썬을 이용한 빠른 알고리즘 개발
  • 프로파이링(profiling) 결과에 따른 부분적인 코드 전환

변환 도구들

  • C 소스파일 / C 라이브러리를 파이썬과 자동 연결하는 위한 도구
  • C언어를 파이썬에 작성 가능
  • 파이썬에 C자료형을 함께 코딩하고 C언어 모듈로 만들어 주는 도구
  • 기타 참고 도구들
  • 파이썬 코드의 실해을 2배에서 100배까지 빠르게 해주는 도구
  • 파이썬 프로그램을 .exe 실행파일로

확장 모듈과 확장 형

  • 확장 모듈(extension module)
  • 파이썬 모듈을 C로 구현
  • 확장 형 (extension type)
  • 파이썬 클래스를 C로 구현

C확장 모듈

  • 모듈 초기화 과정
  • 함수 정의 방법
  • 자료형의 변환
  • 컴파일하기

import 절차

  • import sample 절차
  • 모듈 sample을 찾는다
  • sys.path 경로를 기준
  • C모듈 -> 파이썬 모듈
  • 모듈을 초기화 한다.
  • --
  • 지역 이름 공간에 모듈 이름등을 등록한다.
  • __dict__에 이름 등록

모듈 초기화 과정

  • 모듈 초기화 : ‘init+모듈이름’ 함수 호출

초기화 함수

  • initsample()의 예

void initsample()
{
  PyObject *m;
 
/* 모듈을 생성하고 함수를 등록한다 */
  m = Py_InitModule(
"sample", sample_methods);
 
/* 기타의 초기화 처리 */
  ErrorObject = Py_BuildValue(
"s", "sample error");
 
/* 기타 다른 코드를 .. */
}

함수의 등록

  • 공개 함수의 등록
  • 함수 이름, 함수 포인터, 인수 받는 형식
  • METH_VARARGS : 파이썬에서 C로 튜플 형식의 인수 전달

static struct PyMethodDef sample_methods[] = {
 
/* 함수 이름, 함수 포인터 , 인수 */
 {
"system", sample_system, METH_VARARGS},
 {
NULL,     NULL}
};

함수의 정의

/* self 확장형에서만 사용됨, args - 인수들이 튜플로 묶어서 전달됨 */
static PyObject* sample_system(PyObject*self, PyObject*args)
{
 
char *command;
 intsts;
 
/* 파이썬 인수를 C인수로 변환 */
 
if (!PyArg_ParseTuple(args, "s", &command))
   
return NULL;
 sts = system(command);
 
/* C값을 파이썬 객체로 변환 */
 
return Py_BuildValue("i", sts);
}

컴파일

  • setup.py 만들기

#!/usr/bin/env/python
from distutils.core import setup, Extension
setup(
     name=
"sample",
     version=
"1.0",
     description=
"sample extension module",
     author=
"cosmoslight",
     author_email=
"cosmoslight.huni@gmail.com",
     url=
"http://www.python.or.kr",
     ext_modules=[Extension(
"sample", ["sample.c"])]
    )

  • 컴파일하기
  • 리눅스/원도우 동일함
    $python setup.py build
  • 컴파일하고 설치하기
    $python setup.py install
  • 테스트 하기
  • >>> import samle
    >>> sample.system(‘date’)

인수의 해석

  • 직접 변환 기능 객체
  • init PyArg_ParseTuple(PyObject *arg, char *format, …);

변환

기호

C 자료형

파이썬

자료형

의미

s

char*

String

문자열, 유니코드 문자열

s#

char*, int

String

문자열 s 와 길이

c

char

String

길이가 1인 문자열을 C 문자로 변환

b

char

Integer

파이썬 정수를 1바이트 정수로 변환

h

short int

Integer

파이선 정수를 short int로 변환

i

int

Integer

파이썬 정수형을 C 정수형으로 변환

l

long

Integer

파이썬 정수형을 C의 Long형으로 변환

f

float

Float

C의 float

d

double

Float

C의 double

D

Py_complex

Complex

파이썬 복소수를 Py_complext형으로

O

PyObject*

Object

파이썬 객체를 PyObject형으로


  • 예제

파이썬 호출

C인수 해석

설명

int ok; int i, j; long k, l;

char *s; int size;

f()

ok = PyArg_ParseTuple(args, “”)

전달되는 인수가 없음 확인

f(‘whoops!’)

ok = PyArg_ParseTuple(args, “s”, &s)

문자열 주소를 s에 넘긴다.

f(1, 2, ‘three’)

ok = PyArg_ParseTuple(args, “lls”, &k, &l, &s)

두 개의 정수 객체를 C의 long으로 또 문자열을 받는다.

f((1, 2), ‘three’)

ok = PyArg_ParseTuple(args, “(ii)s#’, &i, &j, &s, &size)

튜플(안의 두개정수), 문자열과 문자열 길이도 함께

f(‘spam’)

f(‘spam’, ‘w’)

f(‘spam’, ‘wb’, 10000)

char *file; char *mode = “r”; int bufsize = 0;

ok = PyArg_ParseTurple(args, “s|si”, &file, &mode, &bufsize);

|는 선택적 인수를 나타냄

하나는 필수, 나머지는 선택적

  • 고급 인수 해석 하기
  • 리스트, 튜플, 사전등의 인수의 해석
  • 변환기호 O를 이용하여 PyObject*로 읽어들인 후 각 자료형에 맞게 처리
  • Python/C API Reference
  • int PySequence_Check(PyObject *o)
  • int PyMapping_Check(PyObject *o)
  • int PyIter_Check(PyObject *o)
  • 수치형
  • int PyInt_Check(PyObject* o)
  • int PyLong_Check(PyObject *p)
  • int PyFloat_Check(PyObject *p)
  • int PyComplex_Check(PyObject *p)
  • 시퀀스
  • int PyString_Check(PyObject *o)
  • int PyUnicode_Check(PyObject *o)
  • int PyBuffer_Check(PyObject *p)
  • int PyTuple_Check(PyObject *p)
  • int PyList_Check(PyObject *p)
  • 사전형
  • int PyDict_Check(PyObject *p)
  • 그외는 공식 API 문서 참조

함수

설명

int PyList_Check (PyObject *p)

리스트 형인지 검사. 리스트 형이면 참 리턴

PyObject* PyList_New (int len)

새로운 리스트 객체 만든다

int PyList_Size (PyObject *list)

리스트의 크기 len(L)

PyObject* PyList_GetItem (PyObject *list, int index)

리스트연산 L[index]와같다

int PyList_SetItem (PyObject *list, int index, PyObject *item)

리스트 연산 L[index] = item

int PyList_Insert (PyObject *list, int index, PyObject *item)

리스트 연산 L.insert(index, item)

int PyList_Append (PyObject *list, PyObject *item)

L.append(item)

PyObject* PyList_GetSlice (PyObject *list, int low, int high)

L[low:high]

int PyList_Sort (PyObject *list)

L.sort()

int PyList_Reverse PyObject *list)

L.reverse()

PyObject* PyList_AsTuple (PyObject *list)

tuple(L)

  • 사전형 객체 API(https://docs.python.org/3.5/c-api/dict.html)

함수

설명

PyObject* PyDict_New ()

새 사전을 만든다

PyObject* PyDict_GetItem(PyObject *p, PyObject *key)

p[key]

PyObject* PyDict_GetItemString(PyObject *p, char *key)

p[key]

int PyDict_SetItem(PyObject*p, PyObject *key, PyObject *val)

p[key] = val

int intPyDict_SetItemString(PyDictObject *p, char *key, PyObject *val)

p[key] = val

PyObject* PyDict_Items (PyObject *p)

p.items() PyListObject 리턴

PyObject* PyDict_Keys (PyObject *p)

p.keys() PyListObject 리턴

PyObject* PyDict_Values (PyObject *p)

p.values() PyListObject 리턴

  • 예제2
  • sum함수의 구현

PyObject *list, *o;
int n, i;
double sum = 0.0;
if (!PyArg_ParseTuple(args, "O", &list))
 
return NULL;

if (PyList_Check(list)) {
 n = PyList_Size(
list);
 
for (i = 0; i < n; i++)
   o = PyList_GetItem(
list, i);
   
if (PyInt_Check(o))
     sum += PyInt_AsLong(o);
   elif(PyFloat_Check(o))
     sum += PyFloat_AsDouble(o);
}
returnPy_BuildValue(
"d", sum);

파이썬 객체의 생성

  • C에서 파이썬 객체를 만드는 방법#1
  • Py_BuildValue를 이용하는 방법
  • PyObject *Py_BuildValue(char *format, …);
  • PyArg_ParseTuple의 format 문자열과 동일
  • Py_BuildValue() 함수 호출 예

함수 호출

리턴 값

Py_BuildValue(“”)

None

Py_BuildValue("i", 123)

정수 123

Py_BuildValue("iii", 123, 456, 789)

tuple (123, 456, 789)

Py_BuildValue("s", "hello")

문자열 ‘hello’

Py_BuildValue("{s:i,s:i}", "abc", 123, "def", 456)

사전 {‘abc’: 123, ‘def: 456}

  • C에서 파이썬 객체를 만드는 방법#2
  • 자료형 생성에 해당하는 API 이용

함수

설명

PyObject* PyInt_FromLong(long ival)

C의 long을 파이썬의 int로

PyObject* PyLong_FromLong(long v)

C의 long을 파이썬으로 long으로

PyObject* PyFloat_FromDouble(dobule v)

C의 double을 파이썬의 float로

PyObject* PyString_FromString(const char *v)

C의 string을 파이썬의 string으로

  • 파이썬 자료형 생성
  • PyObject* PyTuple_New(int len)
  • PyObject* PyList_New(int len)
  • PyObject* PyDict_New()

반환 하기

  • 리턴 자료형
  • PyObject*
  • return PyFloat_FromDouble(5.3)
  • None의 리턴
  • Py_INCREF(Py_NONE);
  • return Py_None;
  • 예외 발생
  • 예외 종료 설정 후 리턴
  • void PyErr_SetString(PyObject *type, char *message);
  • PyErr_SetString(PyExc_IndexError, “my exception”);
  • return NULL: /* NULL은 예외 발생 */

예외가 발생한 경우

  • 예외의 설정
  • PyErr_SetString 으로 예외의 종류를 설정하고 NULL을 리턴
  • 이미 예외가 발생한 경우
  • return NULL; /* 이것만 수행 */

예외의 발생

  • 표준 예외의 발생
  • 표준 예외 변수(PyExc_…)
  • Python/C API 참고(링크)
  • 사용자 예외의 발생
  • 생성 가능 함.

예외의 검출

  • C에서의 예외 검출은
  • 대부분의 API가 예외를 발생할 수 있다.
  • 명시적이어야 한다.
  • 예외의 전달이 이루어지지 않는다.
  • 예외 발생하는지 검사
  • API가 NULL 혹은 -1을 반환
  • 명시적 예외 발생 확인
  • PyObject* PyError_Occured()
  • 리턴 NULL- 예외 없을 때
  • 예외 타입에 대한 레퍼런스
  • 발생한 예외 삭제
  • PyError_Clear()
  • 검수 코드 예(파이썬 코드)

def incr_item(dict, key):
 
try:
   item = dict[key]
 
except KeyError:
   item =
0
 dict[key] = item +
1

  • 검수 코드 예(C 코드)

intincr_item(PyObject*dict, PyObject*key)
{
 
/* Objects all initialized to NULL for Py_XDECREF */
 PyObject*item =
NULL, *const_one = NULL, *incremented_item = NULL;
 intrv=
-1; /* Return value initialized to -1 (failure) */
 item = PyObject_GetItem(dict, key);
 
 
if (item == NULL) {
   
/* Handle KeyErroronly: */
   
if (!PyErr_ExceptionMatches(PyExc_KeyError))
     gotoerror;
   
   
/* Clear the error and use zero: */
   PyErr_Clear();
   item = PyInt_FromLong(
0L);
 
   
if (item == NULL)
     gotoerror;
 }

 const_one = PyInt_FromLong(
1L);
 
if (const_one == NULL)
   gotoerror;

 incremented_item = PyNumber_Add(item, const_one);
 
if (incremented_item == NULL)
   gotoerror;
 
 
if (PyObject_SetItem(dict, key, incremented_item) < 0)
   gotoerror;
 
 rv=
0; /* Success */
 
/* Continue with cleanup code */
 error:
 
 
/* Cleanup code, shared by success and failure path */
 
/* Use Py_XDECREF() to ignore NULL references */
 Py_XDECREF(item);
 Py_XDECREF(const_one);
 Py_XDECREF(incremented_item);
 
 
return rv; /* -1 for error, 0 for success */
}

레퍼런스 카운트

  • 가비지 컬렉터에 필요한 변수
  • 개념들
  • C에서는 레퍼런스 카운트를 명시적으로 다루어야 한다.
  • 객체는 공유되며 레퍼런스는 소유된다.
  • 레퍼런스 카운트 증가 후 반드시 감소해야 한다
  • 리턴되는 레퍼런스는 New Reference 이어야 한다.
  • 함수로 전달되는 인수는 모들 Borrowed Reference 이다.
  • New Reference(새 레퍼런스)
  • 객체의 새로운 레퍼런스
  • Borrowed Reference(빌린 레퍼런스)
  • 다른 소유의 레퍼런스를 잠깐 빌리는 것
  • API에 명시되어 있음.
  • 레퍼런스를 다루는 API
  • Py_INCREF(Py_Object* )  : 레퍼런스 카운트 증가
  • Py_DECREF(Py_Object* )  : 레퍼런스 카운트 감소
  • Py_XINCREF(Py_Object* ) : NULL인 경우 무시하고 처리, 증가
  • Py_XDECREF(Py_Object* ) : NULL인 경우 무시하고 처리, 감소
  • API가 인수로 전달되는 객체로의 레퍼런스를 설정하는 경우
  • 전달된 객체의 레퍼런스를 그대로 이용하는 경우를 steal 이라고 함.
  • 레퍼런스 카운트를 새로 설정하는 경우
  • 레퍼런스 카운트를 잘 못 설정하면?
  • 메모리 누스 현상 발생 : 레퍼런스 카운트를 잘 지우지 못한 경우
  • Segmentation Fault 발생 : 레퍼런스 카운트가 존재하지 않는 참조를 사용하는 경우.

C 확장형 만들기

  • C로 파이썬 클래스 만들기
  • 클래스 객체와 인스턴스 객체의 관계
  • 파이썬 소스

class Square:
 
def __init__(self, limit):
   self.limit = limit
 
def __getitem__(self, k):
   
if k < 0 or self.limit <= k:
     
raise IndexError
   
return k*k
 
def __len__(self):
   
return self.limit
 
def middle(self):
   
return self.limit / 2

s = Square(
10)
print s[3] # 9
print s.middle() # 5

  • 초기화 함수

static struct PyMethodDef square_methods[] = {
{
"Square", square_new, METH_VARARGS, "Create new Square object"},
{
NULL, NULL}
};

void initsquare()
{
 PyObject*m, *d;
 Squaretype.ob_type = &PyType_Type;
 m = Py_InitModule(
"square", square_methods); /* 모듈초기화*/
 ...
}

  • 생성자 정의

static PyObject* square_new(PyObject *self, PyObject *args)
{
 intlimit;
 
if (!PyArg_ParseTuple(args, "i", &limit))   /* args는생성자인수*/
   
return NULL;
 
return (PyObject *)newsquareobject(limit);  /* 인스턴스객체를넘겨준다*/
}

  • 인스턴스 객체 정의 함수

typedefstruct{    /* Square 인스턴스객체*/
 PyObject_HEAD  
/* 파이썬헤더: 레퍼런스카운트와형정보를갖는다*/
 intlimit;      
/* 인스턴스객체멤버를여기부터선언한다*/
} squareobject;

static squareobject* newsquareobject(int limit)
{
 squareobject *self;
 self = PyObject_NEW(squareobject, &Squaretype);
/* squareobject객체생성*/
 
if (self == NULL)     /* 객체생성에실패하면예외발생*/
   
return NULL;
 self->limit = limit;  
/* 생성자에전달된인수처리*/
   
return self;        /* 새로운squareobject형리턴*/
}

  • 인스턴스 객체와 클래스 형의 구조

  • 클래스 형 선언

static PyTypeObject Squaretype= {
 
/* 타입헤더*/ 
                               
/* 모든인스턴스가공유한다*/
 PyObject_HEAD_INIT(
NULL)      /* 타입정보는initsquare에의해채워짐*/
 
0,                            /* ob_size */
 
"Square",                     /* tp_name */
 
sizeof(squareobject),         /* tp_basicsize*/
 
0,                            /* tp_itemsize*/
 
 
/* 표준메써드들*/
 (destructor) square_dealloc,  
/* tp_dealloc*/
 (printfunc)
0,                /* tp_print */
 (getattrfunc) square_getattr,
/* tp_getattr*/
 ...

 
/* 자료형종류*/
 
0,                            /* 수치형메써드들*/
 &square_sequence,            
/* 시퀀스형메써드들*/
 ...
};
/* 추가의다른메써드들은object.h 참조*/

  • 표준 메소드 정의

static PyObject* square_dealloc(squareobject* self)
{
 PyObject_Del(self);
}

static PyObject* square_getattr(squareobject* self, char* name)
{
 
return Py_FindMethod(square_inst_methods, (PyObject*)self, name);
}

  • 사용자 메쏘드 정의
  • __getattr__ 에 의해서 검색 실행됨

static struct PyMethodDef square_inst_methods[] = { /* 추가의메써드들*/
 {
"middle",  square_middle,  METH_VARARGS, "middle point"},
 {
NULL,      NULL        ,   0,            NULL}   /* 마지막표시*/
};

static PyObject* square_middle(squareobject* self, PyObject* args)
{
 
if (!PyArg_ParseTuple(args, ""))
   
return NULL;
 
return Py_BuildValue("i", self->limit / 2);
}

  • 자료형에 따른 메소드 선언

static PySequenceMethods square_sequence = {
 (inquiry)           square_length,  
/* len(x) */
 (binaryfunc)        
0,              /* x + y */
 (intargfunc)        
0,              /* x * n */
 (intargfunc)        square_getitem,
/* x[i], in */
 (intintargfunc)     square_slice,  
/* x[i:j] */
 (intobjargproc)    
0,              /* x[i] = v */
 (intintobjargproc)  
0,              /* x[i:j]=v */
 (objobjproc)        
0,              /* in */
 
/* Added in release 2.0 */
 (binaryfunc)        
0,
 (intargfunc)        
0;
}

static int square_length(squareobject* self)
{
 
return self->limit;   /* 길이정보는정수를그냥넘기면된다*/
}

  • 연산자 처리 흐름

cosmoslight.huni@gmail.com님이 다음 문서를 첨부했습니다.
[강좌]옛날강좌들-열혈강의 파이썬
Google 문서: 온라인에서 문서를 만들고 수정해 보세요.
Google LLC, 1600 Amphitheatre Parkway, Mountain View, CA 94043, USA
다른 사용자가 Google 문서의 문서를 나와 공유하여 발송된 이메일입니다.
Google 문서 로고