E D R , A S I H C RSS

Python3 Tutorial

Contents

1. 개요
2. 내용
2.1. Whetting Your Appetite
2.2. Using the Python Interpreter
2.3. An Informal Introduction to Python
2.3.1. Using Python as a Calculator
2.3.1.1. Numbers
2.3.1.2. Strings
2.3.1.3. Lists
2.3.2. First Steps Towards Programming
2.4. More Control Flow Tools
2.4.1. if Statements
2.4.2. for Statements
2.4.3. The range() Function
2.4.4. break and continue Statements, and else Clauses on Loops
2.4.5. pass Statements
2.4.6. Defining Functions
2.5. More on Defining Functions
2.5.1. Default Argument Values
2.5.2. Keyword Arguments
2.5.3. Arbitrary Argument Lists
2.5.4. Unpacking Argument Lists
2.5.5. Lambda Expressions
2.5.6. Documentation Strings
2.5.7. Function Annotations
2.6. Intermezzo: Coding Style
3. Data Structures
3.1. More on Lists
3.1.1. Using Lists as Stacks
3.1.2. Using Lists as Queues
3.1.3. List Comprehensions
3.1.4. Nested List Comprehensions
4. Modules
5. Input and Output
5.1. Fancier Output Formatting
5.1.1. Old string formatting
5.2. Reading and Writing Files
5.2.1. Methods of File Objects
5.2.2. Saving structured data with json
6. Errors and Exceptions
6.1. Syntax Errors
6.2. Exceptions
6.3. Handling Exceptions
6.4. Raising Exceptions
6.5. User-defined Exceptions
6.6. Defining Clean-up Actions
6.7. Predefined Clean-up Actions
7. Classes
7.1. A Word About Names and Objects
7.2. Python Scopes and Namespaces
7.2.1. Scopes and Namespaces Example
7.3. A First Look at Classes
7.3.1. Class Definition Syntax
7.3.2. Class Objects
7.3.3. Instance Objects
7.3.4. Method Objects
7.3.5. Class and Instance Variables
7.4. Random Remarks
7.5. Inheritance
7.5.1. Multiple Inheritance
7.6. Private Variables
7.7. Odds and Ends
7.8. Exceptions Are Classes Too
7.9. Iterators
7.10. Generators
7.11. Generator Expressions
8. Brief Tour of the Standard Library
8.1. Operating System Interface
8.2. File Wildcards
8.3. Command Line Arguments
8.4. Error Output Redirection and Program Termination
8.5. String Pattern Matching
8.6. Mathematics
8.7. Internet Access
8.8. Dates and Times
8.9. Data Compression
8.10. Performance Measurement
8.11. Quality Control
8.12. Batteries Included
9. Brief Tour of the Standard Library – Part II
9.1. Output Formatting
9.2. Templating
9.3. Working with Binary Data Record Layouts
9.4. Multi-threading
9.5. Logging
9.6. Weak References
9.7. Tools for Working with Lists
9.8. Decimal Floating Point Arithmetic


1. 개요

2. 내용

2.1. Whetting Your Appetite

2.2. Using the Python Interpreter

2.3. An Informal Introduction to Python

  • # : 주석

2.3.1. Using Python as a Calculator

2.3.1.1. Numbers
  • python은 계산기처럼 쓸 수 있음.
    • +, -, *, /, (), **, //, %가 존재.
      • //연산자는 몫을 리턴.
      • x ** y 연산자는 x의 y승 == pow(x, y).
      • -x = x negated
    • int / int = float이니 조심.
  • _: 마지막에 출력된 값을 의미.
  • 복소수도 내장으로 지원함: complex(real, imaginary)
  • divmod(x, y) => (x // y, x % y) 이런 형태로 출력당함
  • round(x, y): 숫자x에서 소수점 자리수를 y개수만 남김.

2.3.1.2. Strings
  • String은 ‘...’ 혹은 “...”사용. 차이는 없음.
    • 다른 언어와 같이\ 를 이용해 특수 문자를 입력 가능.
    • \t, \n, \’ 등.
  • 중간에 있는’를 무효화 시키기 위해서 \를 붙이거나 큰따옴표를 사용
    • 단지 “...” 안의 ‘ 는 허용. ‘...’ 안의 “ 허용. escape 문자 필요없음
  • ’r’을 붙이면 \ 를 특수문자가 아닌 일반 문자로 표현.

>>> print('C:\some\name')  # \n을 개행문자로 인식
C:\some
ame
>>> print(r'C:\some\name')  # r을 앞에 붙인다
C:\some\name
  • String을 +로 더하고, *로 반복할 수 있다.
  • “““....””” 여러 줄을 허용하는 문자열
  • “some” “thing” == “something”
    • 오직 literals 끼리 적용된다.
    • 변수, 수식에서 적용되지 않음
    • 긴 string을 여러 줄에 걸쳐서 쓸 때 사용하면 유용

>>> prefix = 'Py'
>>> prefix 'thon'
SyntaxError: invalid syntax
>>> ('un' * 3) 'ium'
SyntaxError: invalid syntax
  • index를 이용해서 각 chr에 접근 가능하며, 음수도 가능.

 +---+---+---+---+---+---+
 | P | y | t | h | o | n |
 +---+---+---+---+---+---+
 0   1   2   3   4   5   6
-6  -5  -4  -3  -2  -1
  • slicing: [start:end:step]. start는 포함되며, end는 포함되지 않고, 각 항목은 생략 가능.

word = 'Python'
>>> word[0:2]
'Py'
>>> word[:2] + word[2:]
'Python'
>>> word[:2]
'Py'
>>> word[-2:]
'on'
>>> word[:]
‘Python’
  • len(s): string과 기타 등등의 원소의 개수를 반환

2.3.1.3. Lists
  • Python이 가지는 여러가지 자료를 묶는 방식 중 가장 가변적인 형태
  • []로 묶어서 표현.

>>> squares = [1, 4, 9, 16, 25]
>>> squares
[1, 4, 9, 16, 25]
  • [n]으로 index n에 해당하는 데이터에 접근
  • + 로 복수의 list를 append할 수 있다.
  • len(): list와 기타 등등의 원소의 개수를 반환.
  • Slicing
    • String이랑 동일하게 적용.

>>> a = ['a', 'b', 'c']
>>> n = [1, 2, 3]
>>> x = [a, n]
>>> x
[['a', 'b', 'c'], [1, 2, 3]]
>>> x[0]
['a', 'b', 'c']
>>> x[0][1]
'b'

2.3.2. First Steps Towards Programming

  • a, b = b, a+b : 우변을 연산하고 좌변의 대응하는 위치에 맞추어서 대입한다.
  • Indentation 잘못하면 안 돼요.

2.4. More Control Flow Tools

2.4.1. if Statements

  • if (condition):, elif:, else:
  • if 다음에 : 빼먹지 말자.

if x < 0:
    …
elif x == 0:
    …
else:
    ...

2.4.2. for Statements

  • python의 for문은 C처럼 사용자가 정한 종료 조건과 반복 조건을 대로 반복하는 것이 아니라, string, list와 같은 연속된 item 들을 순차적으로 다루게 된다.

>>> # Measure some strings:
... words = ['cat', 'window', 'defenestrate']
>>> for w in words:
...     print(w, len(w))
...
cat 3
window 6
defenestrate 12

2.4.3. The range() Function

  • range(start, stop[, step]) : start부터 stop전까지 step만큼 증가.
  • start <= 범위 < stop
  • range()는 리스트인 것같이 동작해서 리스트 같지만 리스트 아니다! 리스트를 만들지 않으니 저장 공간을 절약한다.

>>> a = ['Mary', 'had', 'a', 'little', 'lamb']
>>> for i in range(len(a)):
...     print(i, a[i])
...
0 Mary
1 had
2 a
3 little
4 lamb

2.4.4. break and continue Statements, and else Clauses on Loops

if 문에서만 else문이 사용되는 다른 언어들과는 다르게 여러 상황에서 선택적으로 else 문을 사용할 수 있다.
  • for/while 루프
    • 반복문 안에 있는 break문에 의해 끝나지 않는 경우 실행이 됨.
  • try - except ( - finally)문
    • try 문 안에서 예외가 발생하지 않을 경우 else 문이 실행 되고, finally 문이 실행됨.

2.4.5. pass Statements

pass문은 어떠한 행동도 일으키지 않으며, 주로 비어있는 구문을 만들 때 사용된다.
더 추상적인 단계에서 생각하는 것을 새로운 코드를 만들 때, pass를 적어두고 나중에 채우기도 한다.
# 오류 발생
while True:

# 오류가 발생하지 않음
while True:
    pass

2.4.6. Defining Functions

def function(args):
    #statements

함수를 실행할 경우 새로운 심볼 테이블이 생성되어 함수 내에서 이용되는 변수들을 해당 테이블에 저장한다. 변수 참조는 처음에는 이 로컬 심볼 테이블을 살펴보고, 다음에는 함수를 감싸고 있던 함수들의 테이블들을 살펴보고, 다음에는 글로벌 심볼 테이블을 살펴보고, 마지막으로는 내장된(built-in) 이름들을 살펴본다. 따라서 global statement를 이용해야 글로벌 변수에 값을 대입할 수 있다.

함수가 실행될 때 실제 인자들은 심볼 테이블을 살펴본다. 고로, 인자는 call by value로 넘어간다. 다만 그 value가 object reference이기 때문이다 함수 내에서 다른 함수를 부를 때 그 함수 호출을 위한 새로운 지역 심볼 테이블을 만든다.

함수 정의하면 현재 심볼 테이블에 등록하고, 함수 이름은 user-defined function으로 인터프리터에 인식된 타입을 가진다. 이 값은 함수로써 쓰일 수 있는 다른 이름으로 대입될 수 있다.
>>> fib
<function fib at 10042ed0>
>>> f = fib
>>> f(100)
0 1 1 2 3 5 8 13 21 34 55 89
  • return은 함수에서 값을 반환함. 없으면 None을 반환함. 함수 끝내기에 실패해도 None반환함
  • object.methodname : 다른 타입의 오브젝트는 다른 타입의 함수를 만든다. 심지어 메소드 이름이 같을 지라도 다른 함수이다.

2.5. More on Defining Functions

  • 함수를 선언할 때 다음과 같은 3가지 방법을 이용해 인자를 받을 수 있다.

2.5.1. Default Argument Values
  • 하나 이상의 인자에 기본 값을 지정한다.

def ask_ok(prompt, retries=4, complaint='Yes or no, please!'):
    ...
  • 기본 값은 함수가 정의된 시점이다.

>>> i = 5
>>> def f(arg=i):
…     print(arg)
>>> i = 6
>>> f()
5
  • 주의! 기본 값은 정의할 때만 초기화가 진행됨. 기본값이 변경 가능한 오브젝트(리스트, 딕셔너리, 대부분의 클래스의 인스턴스)의 경우 실행 할 때 마다 값이 다를 수 있음.

>>> def f(a, L=[]):
…     L.append(a)
...    return L

>>> print(f(1))
[1]
>>> print(f(2))
[1, 2]
>>> print(f(3))
[1, 2, 3]
2.5.2. Keyword Arguments
* kwarg = value 형식으로 사용할 수 있다.
* 위치, 혹은 키워드로 인자를 넣을 수 있다.
  • 키워드 인자 이후에, 키워드 인자가 아닌 것을 넣을 수 없다.
  • 같은 인자에 중복되게 넣을 수 없다. (처음 위치에 있는 키워드에, 위치 인자로 넣고, 또 키워드 인자로 넣는다던가)
    • 없는 키워드 인자를 넣을 수 없다.

def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):
    pass #구현부 생략

parrot(1000)                                          # 1 positional argument
parrot(voltage=1000)                                  # 1 keyword argument
parrot(action='VOOOOOM', voltage=1000000)             # 2 keyword arguments
parrot('a million', 'bereft of life', 'jump')         # 3 positional arguments
parrot('a thousand', state='pushing up the daisies')  # 1 positional, 1 keyword

2.5.3. Arbitrary Argument Lists
  • 0개, 혹은 그 이상의 인자를 가변적으로 받을 수 있다.
  • 키워드 인자 말고도, 위치 인자도 사용 가능하다.

>>> def concat(*args, sep="/"):
...    return sep.join(args)
...
>>> concat("earth", "mars", "venus")
'earth/mars/venus'
>>> concat("earth", "mars", "venus", sep=".")
'earth.mars.venus'
2.5.4. Unpacking Argument Lists
Arbitary Argument Lists와 반대로, 이미 있는 list나 tuple을 인자로 넘길 필요가 있을 경우 unpacking을 이용하면 됨.
  • list/tuple: *

>>> list(range(3, 6))            # normal call with separate arguments
[3, 4, 5]
>>> args = [3, 6]
>>> list(range(*args))            # call with arguments unpacked from a list
[3, 4, 5]
  • 그냥 튜플중에 하나짜리 튜블 생성하는 방법
ex(1,) 콤마뒤에 빈공간
  • dictionaries: **

>>> def parrot(voltage, state='a stiff', action='voom'):
...     print("-- This parrot wouldn't", action, end=' ')
...     print("if you put", voltage, "volts through it.", end=' ')
...     print("E's", state, "!")
...
>>> d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"}
>>> parrot(**d)
-- This parrot wouldn't VOOM if you put four million volts through it. E's bleedin' demised !

2.5.5. Lambda Expressions
람다식을 사용할 수 있다.
  • lambda arguments: expression

2.5.6. Documentation Strings
  • 도큐먼트 작성법: """내용"""
    • 첫 줄은 객체의 목적을 짧게 요약을 해야 하며
    • 둘째 줄은 요약과 본문을 구분 짓기 위해 비어두고
    • 셋째 줄부터는 객체의 호출 방법, 부작용 등등을 서술하면 된다.

def my_function():
    """Do nothing, but document it.
    No, really, it doesn't do anything.
    """
    pass
>>> print(my_function.__doc__)
Do nothing, but document it.

    No, really, it doesn't do anything.

2.5.7. Function Annotations
  • 옵션, metadata 정보, 문서화, 타입 검사와 다른 용도 등을 위해 사용한다
  • 파이썬과 standard library는 안 씀.
  • 사용은 자유
  • 인자이름 뒤에 :로 parameter annotations로 정의한다.
  • ->은 return annotation를 나타남. 함수 이름 선언와 : 사이에 return annotation을 쓴다

>>> def f(ham: 42, eggs: int = 'spam') -> "Nothing to see here":
...     print("Annotations:", f.__annotations__)

>>> f('wonderful')
Annotations: {'eggs': <class 'int'>, 'return': 'Nothing to see here', 'ham': 42}

2.6. Intermezzo: Coding Style

파이썬에서는 PEP8을 준수할 것을 추천한다.
  • 탭 대신 스페이스바 4개를 사용
  • 각 줄이 79글자가 넘지 않도록 개행
  • 함수와 클래스 사이에 빈 줄을 삽입해서 구분
  • docstring을 사용하기
  • 등...

3. Data Structures

3.1. More on Lists

list의 method들:
  • list.append(x): 리스트 끝에 아이템을 추가함.
  • list.extend(L): 리스트에 또다른 리스트 L을 추가한다.
  • list.insert(index,value): index 바로 앞에 값을 추가한다
  • list.remove(x): 값이 x인 첫 번째 아이템을 지움. 값을 못 찾으면 error
  • list.pop(i) : 리스트에서 주어진 index의 값을 지운다. index가 없으면 마지막 아이템을 지운다.
  • list.clear() : 리스트 값 전부 삭제. 리스트 남아있다.
  • list.index(x) : x랑 같은 값을 가진 첫 번째 index를 돌려준다. 없으면 error
  • list.count(x) : x의 갯수 세어줌.
  • list.sort() : list의 item들을 정렬한다
  • list.reverse() : 리스트의 item의 순서를 뒤집는다
  • list.copy() : 리스트의 오브젝트 카피. object를 복사하는 것이 아닌 object reference를 복사한다. (얕은 복사)

3.1.1. Using Lists as Stacks
list의 method들은 list를 Last In First Out인 stack처럼 쓰는데 매우 적합하다.

3.1.2. Using Lists as Queues
list의 끝에 item을 추가하고 빼는 것은 빠르나, 앞에서 이러한 행동을 하는 것은 매우 느리다. 그래서 list를 First In First Out인 queue로 이용하기는 적합하지 않다.
따라서 queue를 이용하고 싶은 경우는 중간에서의 작업은 느리나 양쪽 끝에서의 작업은 빠른 collections.deque를 쓰는 것이 좋다.

3.1.3. List Comprehensions
List Comprehensions를 이용하면 간결하게 list를 생성할 수 있다.
다음 세 가지 표현은 모두 같은 list를 생성한다.
squares = []
for x in range(10):
    squares.append(x**2)

squares = [x**2 for x in range(10)]

squares = list(map(lambda x: x**2, range(10)))

또 다른 예제:
>>> [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]

3.1.4. Nested List Comprehensions
List Comprehensions를 중첩하여 사용할 수 있다.
>>> matrix = [
...     [1, 2, 3, 4],
...     [5, 6, 7, 8],
...     [9, 10, 11, 12],
... ]

[[row[i] for row in matrix] for i in range(4)]
Result : [[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]


4. Modules

5. Input and Output

5.1. Fancier Output Formatting

  • str() vs repr()
    • str(): 사람이 읽기 위한 용도로 string으로 변환
    • repr(): eval()을 사용하기 위한 용도로 string으로 변환

>>> s = 'Hello, world.'
>>> str(s)
'Hello, world.'
>>> repr(s)
"'Hello, world.'"
  • str.format() method를 이용하면 노가다를 뛰지 않고도 깔끔하게 출력이 가능

>>> for x in range(1, 3):
...     print('{0:2d} {1:3d} {2:4d}'.format(x, x*x, x*x*x))
...
 1   1    1
 2   4    8
 3   9   27
>>> print('The story of {1}, {0}, and {other}.'.format('Manfred','Bill',
                                                       other='Georg'))
The story of Bill, Manfred, and Georg.
>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678}
>>> print('Jack: {0[Jack]:d}; Sjoerd: {0[Sjoerd]:d}; '
...       'Dcab: {0[Dcab]:d}'.format(table))
Jack: 4098; Sjoerd: 4127; Dcab: 8637678
>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678}
>>> print('Jack: {Jack:d}; Sjoerd: {Sjoerd:d}; Dcab: {Dcab:d}'.format(**table))
Jack: 4098; Sjoerd: 4127; Dcab: 8637678
  • vars()를 이용하면 local variables를 담은 dictionary를 얻을 수 있음. 위의 예제와 쓰면 궁합이 좋음.
  • str.rjust(n), str.ljust(n), str.center(n): n사이즈에 맞게 정렬된 string을 반환. str이 이미 n보다 길면 무시.
    • 이와 같은 문제를 해결하기 위해 str.ljust(n)[:n] 같은 짓을 가능.
  • str.zfill(n): n사이즈에 맞게 0이 삽입된 string을 반환.
5.1.1. Old string formatting
  • %typeIndicator
    • 구식이다.

print(‘The value of PI is %5.3f.’ % math.pi)

5.2. Reading and Writing Files

  • open(filename, mode): 파일 열기
    • mode
      • ‘r’: 읽기 (기본값)
      • ‘w’: 쓰기
      • ‘a’: 이어쓰기
      • ‘r+’,’w+’: 쓰고 읽기
      • ‘b’: 바이너리로 열기 (없으면 텍스트로 읽음)
  • binary vs text
    • text mode에서는 line ending을 플랫폼에 맞는 형식으로 변환.
    • 따라서 text가 아닌 파일을 text 모드로 열면 파일이 변형될 수 있음.
5.2.1. Methods of File Objects
  • read(size)
    • size만큼 파일을 읽는다. size가 지정되지 않거나 음수면 메모리가 허용하는 만큼 읽음.
    • 끝에 도달하면 빈 string인 ‘’를 반환
  • readline() / readlines()
    • 한 줄 읽어오는 메소드/한줄씩 묶어서 리스트로 제공하는 메소드
    • list(file)로도 readlines와 같은 효과
    • 다음과 같이 for문을 이용할 수도 있음:

for line in f:
	print(line, end=’’)
  • write(string)
    • 파일에 string을 씁니다. string만 가능하니 다른 것을 쓰고 싶다면 str(object)로 변환 후 이용.
  • seek(index,from) :
    • from
      • 0 : 파일의 시작점을 기준으로
      • 1 : 현재 보고 있는 바이트를 기준으로(tell()로 보이는 그거)
      • 2 : 파일의 마지막 바이트를 기준으로
  • tell()
    • 파일 내의 현재 지정하고 있는 바이트 위치를 알려줌
  • close()
    • 파일을 닫음. 닫고 나서 해당 파일을 쓰려고 하면 오류가 남.
  • closed
    • NOT A METHOD
    • 닫혔는지 여부를 boolean으로 알려줌
5.2.2. Saving structured data with json
  • json = JavaScript Object Notation
  • import json
  • json.load(json file) 도 파일 읽기 시스템. 읽고 난 뒤에는 마지막으로 간다. 고로 여러번 읽을 수 없다.
  • json.dumps(obj): obj를 json 형식으로 전환
  • json.dump(obj, file) : file에 쓰기

6. Errors and Exceptions

6.1. Syntax Errors

  • SyntaxError - 문법 오류. 파싱을 하다 문제가 생기면 발생
  • 자주 틀리는 문법 오류
    • 들여쓰기
    • 따옴표
    • :

6.2. Exceptions

  • 문법적으로는 맞지만 실행하려고 시도하는 중에 발생하는 에러.
    • ZeroDivisionError, NameError, TypeError, 기타 등등
    • Built-in Exception의 경우 발생시 Exception이름과 이유가 출력됨.

6.3. Handling Exceptions

  • 어떠한 Exception들에 대해 개발자가 선택적으로 다룰 수 있음. java와 유사.

try:
	x = 1 / 0
except ZeroDivisionError:
	print(“...”)
  • 여러 개의 예외처리는 튜플로 가능하다.

except (RuntimeError, TypeError, NameError):
	pass
  • as 키워드를 이용해서 객체 이용 가능

except OSError as err:
	print("OS error: {0}".format(err))
  • Error 명을 적지 않고 except:와 같이 쓰면 모든 Error에 대해 처리. 단, 매우 신중하게 사용해야 하며, 다음처럼 메시지를 출력하고 다시 Error를 선언하는 식으로 쓸 수 있음.

except:
	print("Unexpected error")
	raise
  • else: 구문: try 구문에서 exception이 발생되지 않은 경우 실행
  • built-in Exception class들은 인자를 넘겨줄 경우 instance.args 로 접근이 가능하며, __str__()은 이 .args를 출력해줌.

>>> try:
...    raise Exception('spam', 'eggs')
... except Exception as inst:
...    print(type(inst))
...    print(inst.args)
...    print(inst)

<class 'Exception'>
('spam', 'eggs')
('spam', 'eggs')

6.4. Raising Exceptions

  • raise 구문: 프로그래머가 원하는 Exception을 일으킨다.
    • Exception을 상속받은 Class 들만 가능하다
      • class className(Exception): 상속 방법

6.5. User-defined Exceptions

  • Exception Class를 상속하여 새로운 Exception class를 만들 수 있다.
    • __init__(), __str__()이 기본적으로 구현되어있으나, override 가능.
    • 가능하면 ‘~Error’ 라는 이름으로 하는 것이 좋음.

6.6. Defining Clean-up Actions

  • finally: - try 문이 완전히 종료되기 직전에 반드시 실행되는 내용.
    • except 문으로 사용자가 지정한 Exception이 아닌 다른 Exception이 발생할 경우 finally 문이 실행된 이후 다시 해당 Exception을 발생시킨다.
    • try문이 끝나고 else문이 있으면 else문이 실행된 다음에 실행 됨.

6.7. Predefined Clean-up Actions

with open("myfile.txt") as f:
    for line in f:
        print(line, end="")
  • with 에서 나오면 open된 file을 close 해준다.
    • 조금 더 일반적으로 설명하자면, with 구문을 벗어나면 사용된 객체를 자동으로 정리해줌.
    • __exit__(), __enter__()가 구현되어 있는 class의 경우 with 구문을 사용 할 수 있으며, 다른 built-in class들도 구현이 되어 있음.

7. Classes

7.1. A Word About Names and Objects

class도 Object이다.

7.2. Python Scopes and Namespaces

  • statements
    • nonlocal
    • global
7.2.1. Scopes and Namespaces Example
def scope_test():
    def do_local():
        spam = "local spam"
    def do_nonlocal():
        nonlocal spam
        spam = "nonlocal spam"
    def do_global():
        global spam
        spam = "global spam"
    spam = "test spam"
    do_local()
    print("After local assignment:", spam)
    do_nonlocal()
    print("After nonlocal assignment:", spam)
    do_global()
    print("After global assignment:", spam)

scope_test()
print("In global scope:", spam)
Result
After local assignment: test spam
After nonlocal assignment: nonlocal spam
After global assignment: nonlocal spam
In global scope: global spam

7.3. A First Look at Classes

7.3.1. Class Definition Syntax
def와 유사.
class MyClass:
    """A simple example class"""
    i = 12345
    def f(self):
        return 'hello world'

7.3.2. Class Objects
class objects는 다음과 같은 2가지의 작업이 가능하다.
  • attribute reference
    • MyClass.i, MyClass.f, MyClass.__doc__과 같이 선언된 class의 attribute에 접근.
  • instantiation
    • x= MyClass() 와 같은 문법으로 인스턴스화 가능.
    • 인스턴스화 될 때 __init__(self) method가 자동으로 실행. 따라서 객체의 초기화를 진행할 수 있음.
      • __init__(self, x, y)처럼 인자를 받을 수도 있음.
      • overloading을 시도했으나 overriding이 되버림. default parameter를 이용해야 하는 듯?

7.3.3. Instance Objects
instance object는 attribute reference만 가능.
  • data attribute
  • method
    • object에 종속된 function
7.3.4. Method Objects
  • x.f() == MyClass.f(x)
  • x.f는 method object이기 때문에 다음과 같이 대입 후 사용 가능.

xf = x.f
xf()
7.3.5. Class and Instance Variables
class Dog:
    kind = 'canine'              # 클래스 변수
    def __init__(self, name):
        self.name = name         # 인스턴스 변수
클래스 변수는 모든 인스턴스가 공유하고, 인스턴스 변수는 각 객체마다 따로 지니는 변수.
인스턴스 변수를 클래스 변수에 선언하지 않도록 주의

7.4. Random Remarks

  • Data, Method, Function 등등이 서로 충돌이 일어날 수 있으니 적합한 네이밍 (카멜케이스, 헝가리안 등)을 사용하는 것이 좋음.
  • python에서는 C의 struct와 같은 추상 데이터 타입을 완전히 구현하는 것이 불가능하다.
    • 사용자들이 임의로 변경을 할 수 있기 때문
  • method 첫 인자인 ‘self’는 다른 이름으로 둘 수도 있지만, 가독성을 위해 냅두는 것이 좋음.
  • class 속성으로 들어가있는 function은 반드시 안에서 구현이 될 필요 없이 대입을 해도 사용 할 수 있음.

# Function defined outside the class
def f1(self, x, y):
    return min(x, x+y)

class C:
    f = f1
    def g(self):
        return 'hello world'
    h = g
  • method에서 다른 method를 부르고 싶을 경우 self.another_method() 식으로 호출.
  • 모든 객체는 object.__class__를 동해 class를 확인할 수 있음.

7.5. Inheritance

class DerivedClassName(BaseClassName):
    <statement>
    ...	
  • isinstance() : 인스턴스인지 확인
    • isinstance(obj, int) 는 True
  • issubclass() : 상속을 확인
    • issubclass(bool, int) 는 True
    • issubclass(float, int) 는 False

7.5.1. Multiple Inheritance
  • 다중상속이 가능하다.

class DerivedClassName(Base1, Base2, Base3):
  • method, variable등을 호출 할 때 가장 먼저 DerivedClass를 탐색하고, 왼쪽부터 차례대로 찾아 다님.
    • 실제로는 더 복잡한 방법으로 진행된다고는 하는데...

7.6. Private Variables

  • _variable은 ‘밖에서 쓰이면 안된다는’ variable이라는 약속. 쓸 수는 있으나. 쓰지 말자.
  • Private object = __objectname
  • object 이름 앞에 __ 붙이면 private.

class Mapping:
    def __init__(self, iterable):
        self.items_list = []
        self.__update(iterable)

    def update(self, iterable):
        for item in iterable:
            self.items_list.append(item)

    __update = update   # private copy of original update() method

class MappingSubclass(Mapping):

    def update(self, keys, values):
        # provides new signature for update()
        # but does not break __init__()
        for item in zip(keys, values):
            self.items_list.append(item)
  • 그러니 실제로 Private가 아님
  • object._classname__spam 으로 접근 가능하다

7.7. Odds and Ends

class Employee:
    pass

john = Employee()    # john 이라는 이름의 빈 Employee를 만듬

john.name = 'John Doe'
john.dept = 'computer lab'
john.salary = 1000

7.8. Exceptions Are Classes Too

raise Class == raise Class()
raise Instance
class CustomException(Exception):
    pass
  • 하나의 try문에 여러 except 문이 있을 경우, 가장 위에서부터 해당 class의 인스턴스인지 확인.

7.9. Iterators

  • for문은 실행시 object의 iter()를 호출해 나온 iterator object를 사용.
    • iterator object는 다음 element를 return하고, 더이상 element가 없으면 StropIteration exception을 raise하는 __next__() method를 가지고 있음.
    • __next__()next() built-in function을 통해서도 부를 수 있음.

>>> s = 'abc'
>>> it = iter(s)
>>> it
<iterator object at 0x00A1DB50>
>>> next(it)
'a'
>>> next(it)
'b'
>>> next(it)
'c'
>>> next(it)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
    next(it)
StopIteration
class Reverse:
    """Iterator for looping over a sequence backwards."""
    def __init__(self, data):
        self.data = data
        self.index = len(data)
    def __iter__(self):
        return self
    def __next__(self):
        if self.index == 0:
            raise StopIteration
        self.index = self.index - 1
        return self.data[self.index]
>>> rev = Reverse('spam')
>>> iter(rev)
<__main__.Reverse object at 0x00A1DB50>
>>> for char in rev:
...     print(char)
...
m
a
p
s

7.10. Generators

  • Generator는 iterator를 만듦. 일반적인 function가 유사하지만 return 대신 yield를 사용. next() 가 호출될 때 마다 실행을 멈춘 자리에서 다시 작업을 수행.
  • __iter__()__next__() method가 자동으로 생성되서 코드가 간단해지고, 각 call 사이마다 local variables과 실행 상태를 저장하고, generator가 끝난 이후 자동으로 StropIteration이 raise되는 것이 특징. 따라서 일반적인 구현보다 쉬워짐.

def reverse(data):
    for index in range(len(data)-1, -1, -1):
        yield data[index]
>>> for char in reverse('golf'):
...     print(char)
...
f
l
o
g

7.11. Generator Expressions

예제 :
>>> sum(i*i for i in range(10))                 # sum of squares
285

>>> xvec = [10, 20, 30]
>>> yvec = [7, 5, 3]
>>> sum(x*y for x,y in zip(xvec, yvec))         # dot product
260

>>> data = 'golf'
>>> list(data[i] for i in range(len(data)-1, -1, -1))
['f', 'l', 'o', 'g']

8. Brief Tour of the Standard Library

8.1. Operating System Interface

  • os : os 모듈은 os와 상호작용하는 함수를 제공
    • os.getcwd() : 현재 디렉토리 리턴 cwd와 같음
    • os.chdir(path) : 현재 디렉토리를 path로 변경
    • os.system(command) : command를 시스템 쉘에서 실행
  • shutil : os에 비해 더 상위 인터페이스를 제공
    • shutil.copyfile(src, dst, *, follow_symlinks=True) : 파일 copy
    • shutil.move(src, dst) : src를 dst로 이동시킴

8.2. File Wildcards

  • glob 모듈은 와일드카드(*, ?) 검색을 통한 파일 이름이 담긴 list를 반환하는 function을 가지고 있음.
    • glob.glob(pathname) : 검색한 파일 리스트를 보여준다

8.3. Command Line Arguments

  • sys.argv): 인자(python demo.py one two three) 를 list로 반환

8.4. Error Output Redirection and Program Termination

  • sys 모듈은 stdin, stdout, stderr 속성을 가지고 있으며, 파일이나 다른 output으로 redirection이 가능.
sys.stderr.write('Warning, log file not found starting a new one\n')

8.5. String Pattern Matching

re 모듈은 정규표현식 (regular expression) 도구들을 제공.
  • re.findall(pattern, string): 매칭되는 문자들을 list로 반환
  • re.sub(pattern, repl, string): 매칭되는 문자들을 repl로 변환한 string을 반환

8.6. Mathematics

  • math 모듈은 float에 대한 C라이브러리 함수에 접근 가능하다.
    • math.cos(x) : cos(x)값을 반환
    • math.log(x[, base]) : base를 밑으로 한 log값을 반환. base가 없을 시 밑은 e가 된다.

  • random 모듈은 무작위 선택에 대한 함수를 제공한다.
    • random.random : 무작위의 float을 반환
    • random.randrange(number) : range(number) 에서 정수 하나 반납

8.7. Internet Access

urllib.request 모듈은 인터넷 연결을 통한 작업들을 쉽게 할 수 있는 함수들이 있음.
  • email, ftp, html, url, 등
로컬 호스트에 메일서버가 있다면, stmplib 모듈을 이용해서 메일을 보낼 수 있음

8.8. Dates and Times

datetime 모듈은 시간과 시간대를 다룸.
  • datetime.date 클래스는 특정한 날짜를 저장 (2013, 4, 5)
    • date.strftime을 이용하면 포멧을 이용해서 출력 가능.

>>> now.strftime("%m-%d-%y. %d %b %Y is a %A on the %d day of %B.")
'12-02-03. 02 Dec 2003 is a Tuesday on the 02 day of December.'
  • datetime.timedelta 클래스는 기간을 저장 date(2014, 2, 1) - date(2014, 1, 1) == datetime.timedelta(31)

8.9. Data Compression

zlib, gzip, bz2, lzma, zipfile, tarfile 등의 모듈에서 압축을 지원한다. (여기서는 zlib을 사용)
  • zlib.compress(byte) : byte을 압축
  • zlib.decompress(byte): 압축한 byte을 압축하기 전으로 풀기

  • type(b”saeou”) = <class 'bytes'>
  • type(r”saeouha”) = <class 'str'>

8.10. Performance Measurement

  • timeit = 작은 코드의 실행 시간을 측정하기 위한 도구
  • Timer(“code”, “code”, …).timeit() : 가장 왼쪽의 코드(str)를 실행 -> 삭제 -> 없을 때까지 루프
  • Timer(“code”).timeit() 으로 무한 루프도 가능하다. 안 끝날 뿐.

8.11. Quality Control

  • doctest모듈은 docstring안에 있는 테스트 코드를 실행시킴.

def average(values):
    """Computes the arithmetic mean of a list of numbers.

    >>> print(average([20, 30, 70]))
    40.0
    """
    return sum(values) / len(values)

import doctest
doctest.testmod()   # automatically validate the embedded tests

  • unittest 모듈은 doctest보다는 복잡하지만, 더 상세한 테스트를 진행할 수 있음.

import unittest

class TestStatisticalFunctions(unittest.TestCase):

    def test_average(self):
        self.assertEqual(average([20, 30, 70]), 40.0)
        self.assertEqual(round(average([1, 5, 7]), 1), 4.3)
        with self.assertRaises(ZeroDivisionError):
            average([])
        with self.assertRaises(TypeError):
            average(20, 30, 70)

unittest.main() # Calling from the command line invokes all tests


8.12. Batteries Included

  • python은 이런 식으로 쓰기 쉬운 모듈들이 많음.

9. Brief Tour of the Standard Library – Part II


9.1. Output Formatting

  • reprlib 모듈
    • 긴 object의 출력 결과를 줄여서 출력해줌.

>>> reprlib.repr(set('supercalifragilisticexpialidocious'))
"set(['a', 'c', 'd', 'e', 'f', 'g', ...])"

  • pprint 모듈
    • built-in / 사용자가 만든 객체들을 좀 더 읽기 편한 방법으로 출력
    • 결과값이 한 줄보다 길 경우 line break와 indentation을 추가

  • textwrap모듈은 너비에 맞게 출력

  • locale모듈은 특정한 지역의 출력 형식 데이터베이스에 접근, 해당 지역의 출력 형식에 맞게 출력을 할 수 있도록 한다.

>>> import locale
>>> locale.setlocale(locale.LC_ALL, 'English_United States.1252')
'English_United States.1252'
>>> conv = locale.localeconv()          # get a mapping of conventions
>>> x = 1234567.8
>>> locale.format("%d", x, grouping=True)
'1,234,567'
>>> locale.format_string("%s%.*f", (conv['currency_symbol'],
...                      conv['frac_digits'], x), grouping=True)
'$1,234,567.80'

9.2. Templating

  • string모듈의 Template class
  • Template()로 규격을 만들고 $가 붙은 부분에 단어를 삽입 할 수 있다.
    • 그냥 $를 사용하고 싶으면 $$를 이용

 from string import Template
 t = Template('${village}folk send $$10 to $cause.')
 t.substitute(village='Nottingham', cause='the ditch fund')
Result : 'Nottinghamfolk send $10 to the ditch fund.'
  • $가 붙은 모든 변수에 단어를 삽입하지 않았을 시 substitute()함수를 사용하면 KeyError가 .발생
    • 이 때는 safe_substitute()함수를 사용
t.safe_substitute()
Result : ‘${Village}folk send $10 to $cause.’

9.3. Working with Binary Data Record Layouts

struct 모듈의 pack(), unpack() 함수를 이용하면 바이너리 파일의 헤더 부분과 을 쉽게 다룰 수 있음.
data = open(‘myfile.zip’, ‘rb’).read()
start = 14
fields = struct.unpack('<IIIHH', data[start:start+16])
crc32, comp_size, uncomp_size, filenamesize, extra_size = fields
  • ‘H’와 ‘I’ 는 각각 2/4 bytes unsigned numbers를 의미하고, '<'는 표준 크기의 little-endian byte order임을 명시함.

9.4. Multi-threading

python에서의 멀티 스레딩은 threading 모듈에 있는 Thread class 를 통해 할 수 있음.
  • run() 을 오버라이딩 한 다음
  • start() 를 호출하는 방식.
  • join() 메서드를 이용해서 해당 thread가 일이 끝날 때 까지 기다릴 수 있음.

9.5. Logging

logging 모듈은 다양하고 유연한 로그 기능을 지원. 기본적으로 sys.strerr 으로 출력되며, info와 debug 메시지는 무시된다. 설정을 통해 email, sockets, HTTP server 등으로 보낼 수도 있으며, 메시지 수준에 따라 다른 곳으로 보낼 수도 있다.
  • 출력용 메서드들: debug(), info(), warning(), error(), critical()

9.6. Weak References

파이선은 garbage collection(gc module로 접근 가능) 을 이용해서 자동으로 메모리를 관리한다. 객체는 더 이상 참조가 되지 않을 경우 gc에 의해 자동으로 정리된다.
하지만, 다른 곳에서 객체를 사용하는 동안에만 객체를 추적하고 싶은 경우 이러한 처리법은 문제가 될 수 있다. 이러한 경우 객체를 참고하기 때문에 gc에 의해 정리가 되지 않기 때문이다. 이럴 경우 weakref 모듈을 사용하면 weakref에 의해 참조가 될 경우에도 gc에 의해 자동으로 정리가 된다.
>>> a = A(10)
>>> d = weakref.WeakValueDictionary()
>>> d['primary'] = a

9.7. Tools for Working with Lists

  • array 모듈
    • 같은 종류의 데이터만 담을 수 있으며, 더 작은 메모리를 차지

>>> from array import array
>>> a = array('H', [4000, 10, 700, 22222])
>>> sum(a)
26932
  • collection 모듈의 deque 오브젝트
    • list보다 왼쪽에서의 pop/append는 빠르지만 중간에 있는 데이터를 다룰 때는 느림. 따라서 queue의 목적으로 사용에 적합.

>>> from collections import deque
>>> d = deque(["task1", "task2", "task3"])
>>> d.append("task4")
>>> print("Handling", d.popleft())
Handling task1
  • bisect(Array bisection algorithm) 모듈은 정렬된 list를 다루는 함수가 있음

>>> import bisect
>>> scores = [(100, 'perl'), (200, 'tcl'), (400, 'lua'), (500, 'python')]
>>> bisect.insort(scores, (300, 'ruby'))
>>> scores
[(100, 'perl'), (200, 'tcl'), (300, 'ruby'), (400, 'lua'), (500, 'python')]
  • heapq 모듈은 list 형을 기반으로 heap 을 이용할 수 있도록 함.
    • heapify(), heappush(), heappop() 함수 등이 있음.

9.8. Decimal Floating Point Arithmetic

  • 실수 연산을 위한 decimal 모듈, Decimal 클래스
    • 정확한 진수 표현이 필요한 금융 프로그램이나 기타 등등
    • 정밀한 제어
    • 중요한 소수 자릿수 계산
    • 손으로 한 계산과 결과가 같기를 기대한 계산
    • 정확한 반올림이 필요한 계산
  • 기본 실수 연산은 binary floating 연산의 한계가 있다 부동소수점에 관한 PDF글

>>> from decimal import *
>>> Decimal('1.0') % Decimal('.10')
Decimal('0.00')
>>> 1.0 % 0.1
0.09999999999999995
>>> [Decimal('0.1')]*10
[Decimal('0.1'), Decimal('0.1'), Decimal('0.1'), Decimal('0.1'), Decimal('0.1'), Decimal('0.1'), Decimal('0.1'), Decimal('0.1'), Decimal('0.1'), Decimal('0.1')]
>>> sum([Decimal('0.1')]*10)
Decimal('1.0')
>>> [0.1]*10
[0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]
>>> sum([0.1]*10)
0.9999999999999999
Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2021-02-07 05:24:08
Processing time 0.0698 sec