Difference between r1.40 and the current
@@ -2,7 +2,7 @@
== 개요 ==
* [https://docs.python.org/3/tutorial]의 내용을 [열파참/금요일]에서 정리.
* 번역이 아닌 정리다보니, 내용의 차이가 있을 수 있음... 이 아니라 있음.
* 번역이 아닌 정리다보니, 내용의 차이가 있음.
* 스터디시만 사용하는 독스: http://goo.gl/11ZcFB== 내용 ==
@@ -25,11 +25,11 @@
===== Strings =====
* String은 ‘...’ 혹은 “...”사용. 차이는 없음.
* 다른 언어와 같이{{{\}}}를 이용해 특수 문자를 입력 가능.
* 다른 언어와 같이{{{\ }}}를 이용해 특수 문자를 입력 가능.
* {{{\t}}}, {{{\n}}}, {{{\’}}} 등.* 중간에 있는’를 무효화 시키기 위해서 \를 붙이거나 큰따옴표를 사용
* 단지 “...” 안의 ‘ 는 허용. ‘...’ 안의 “ 허용. escape 문자 필요없음
* ’r’을 붙이면 {{{\}}}를 특수문자가 아닌 일반 문자로 표현.
* ’r’을 붙이면 {{{\ }}}를 특수문자가 아닌 일반 문자로 표현.
{{{>>> print('C:\some\name') # \n을 개행문자로 인식
C:\some
@@ -103,7 +103,271 @@
* Indentation 잘못하면 안 돼요.
=== More Control Flow Tools ===
=== Data Structures ===
=== Modules ===
=== Input and Output ===
==== Fancier Output Formatting ====
=== More Control Flow Tools ===
==== if Statements ====
* {{{if (condition):}}}, {{{elif:}}}, {{{else:}}}
* {{{if}}} 다음에 {{{:}}} 빼먹지 말자.
{{{
if x < 0:
…
elif x == 0:
…
else:
...
}}}
==== 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
}}}
==== 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
}}}
==== break and continue Statements, and else Clauses on Loops ====
if 문에서만 else문이 사용되는 다른 언어들과는 다르게 여러 상황에서 선택적으로 else 문을 사용할 수 있다.
* for/while 루프
* 반복문 안에 있는 break문에 의해 끝나지 않는 경우 실행이 됨.
* try - except ( - finally)문
* try 문 안에서 예외가 발생하지 않을 경우 else 문이 실행 되고, finally 문이 실행됨.
==== pass Statements ====
{{{pass}}}문은 어떠한 행동도 일으키지 않으며, 주로 비어있는 구문을 만들 때 사용된다.
더 추상적인 단계에서 생각하는 것을 새로운 코드를 만들 때, {{{pass}}}를 적어두고 나중에 채우기도 한다.
{{{
# 오류 발생
while True:
}}}
{{{
# 오류가 발생하지 않음
while True:
pass
}}}
==== 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}}} : 다른 타입의 오브젝트는 다른 타입의 함수를 만든다. 심지어 메소드 이름이 같을 지라도 다른 함수이다.
=== More on Defining Functions ===
* 함수를 선언할 때 다음과 같은 3가지 방법을 이용해 인자를 받을 수 있다.
===== 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]
}}}
===== 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
}}}
===== 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'
}}}
===== 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 !
}}}
===== Lambda Expressions =====
람다식을 사용할 수 있다.
* {{{lambda arguments: expression}}}
===== 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.
}}}
===== 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}
}}}
==== Intermezzo: Coding Style ====
파이썬에서는 [http://legacy.python.org/dev/peps/pep-0008/ PEP8]을 준수할 것을 추천한다.
* 탭 대신 스페이스바 4개를 사용
* 각 줄이 79글자가 넘지 않도록 개행
* 함수와 클래스 사이에 빈 줄을 삽입해서 구분
* docstring을 사용하기
* 등...
==== 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를 복사한다. (얕은 복사)
===== Using Lists as Stacks =====
list의 method들은 list를 Last In First Out인 stack처럼 쓰는데 매우 적합하다.
===== Using Lists as Queues =====
list의 끝에 item을 추가하고 빼는 것은 빠르나, 앞에서 이러한 행동을 하는 것은 매우 느리다. 그래서 list를 First In First Out인 queue로 이용하기는 적합하지 않다.
따라서 queue를 이용하고 싶은 경우는 중간에서의 작업은 느리나 양쪽 끝에서의 작업은 빠른 {{{collections.deque}}}를 쓰는 것이 좋다.
===== 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)]
}}}
===== 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]]}}}
=== Input and Output ===
==== Fancier Output Formatting ====
@@ -327,7 +591,7 @@
* overloading을 시도했으나 overriding이 되버림. default parameter를 이용해야 하는 듯?
===== Instance Objects =====
instance object는 attribute reference만 가능.
* method
* object에 종속된 function
===== Instance Objects =====
instance object는 attribute reference만 가능.
* data attribute* method
* object에 종속된 function
@@ -347,3 +611,397 @@
}}}
클래스 변수는 모든 인스턴스가 공유하고, 인스턴스 변수는 각 객체마다 따로 지니는 변수.
인스턴스 변수를 클래스 변수에 선언하지 않도록 주의
클래스 변수는 모든 인스턴스가 공유하고, 인스턴스 변수는 각 객체마다 따로 지니는 변수.
인스턴스 변수를 클래스 변수에 선언하지 않도록 주의
==== 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를 확인할 수 있음.
==== Inheritance ====
{{{
class DerivedClassName(BaseClassName):
<statement>
...
}}}
* {{{isinstance()}}} : 인스턴스인지 확인
* {{{isinstance(obj, int)}}} 는 True
* {{{issubclass()}}} : 상속을 확인
* {{{issubclass(bool, int)}}} 는 True
* {{{issubclass(float, int)}}} 는 False
===== Multiple Inheritance =====
* 다중상속이 가능하다.
{{{
class DerivedClassName(Base1, Base2, Base3):
}}}
* method, variable등을 호출 할 때 가장 먼저 DerivedClass를 탐색하고, 왼쪽부터 차례대로 찾아 다님.
* 실제로는 더 복잡한 방법으로 진행된다고는 하는데...
==== 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 으로 접근 가능하다
==== Odds and Ends ====
{{{
class Employee:
pass
john = Employee() # john 이라는 이름의 빈 Employee를 만듬
john.name = 'John Doe'
john.dept = 'computer lab'
john.salary = 1000
}}}
==== Exceptions Are Classes Too ====
{{{raise Class}}} == {{{raise Class()}}}
{{{raise Instance}}}
{{{
class CustomException(Exception):
pass
}}}
* 하나의 try문에 여러 except 문이 있을 경우, 가장 위에서부터 해당 class의 인스턴스인지 확인.
==== 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
}}}
==== 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
}}}
==== 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']
}}}
=== Brief Tour of the Standard Library ===
==== 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로 이동시킴
==== File Wildcards ====
* {{{glob}}} 모듈은 와일드카드({{{*}}}, {{{?}}}) 검색을 통한 파일 이름이 담긴 list를 반환하는 function을 가지고 있음.
* {{{glob.glob(pathname)}}} : 검색한 파일 리스트를 보여준다
==== Command Line Arguments ====
* {{{sys.argv)}}}: 인자({{{python demo.py one two three}}}) 를 list로 반환
==== 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')}}}
==== String Pattern Matching ====
{{{re}}} 모듈은 정규표현식 (regular expression) 도구들을 제공.
* {{{re.findall(pattern, string)}}}: 매칭되는 문자들을 list로 반환
* {{{re.sub(pattern, repl, string)}}}: 매칭되는 문자들을 repl로 변환한 string을 반환
==== 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) 에서 정수 하나 반납
==== Internet Access ====
{{{urllib.request}}} 모듈은 인터넷 연결을 통한 작업들을 쉽게 할 수 있는 함수들이 있음.
* email, ftp, html, url, 등
로컬 호스트에 메일서버가 있다면, {{{stmplib}}} 모듈을 이용해서 메일을 보낼 수 있음
==== 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)}}}
==== 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'>
==== Performance Measurement ====
* timeit = 작은 코드의 실행 시간을 측정하기 위한 도구
* {{{Timer(“code”, “code”, …).timeit()}}} : 가장 왼쪽의 코드(str)를 실행 -> 삭제 -> 없을 때까지 루프
* {{{Timer(“code”).timeit()}}} 으로 무한 루프도 가능하다. 안 끝날 뿐.
==== 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
}}}
==== Batteries Included ====
* python은 이런 식으로 쓰기 쉬운 모듈들이 많음.
=== Brief Tour of the Standard Library – Part II ===
==== 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'
}}}
==== 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.’
==== 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임을 명시함.
==== Multi-threading ====
python에서의 멀티 스레딩은 {{{threading}}} 모듈에 있는 {{{Thread}}} class 를 통해 할 수 있음.
* {{{run()}}} 을 오버라이딩 한 다음
* {{{start()}}} 를 호출하는 방식.
* {{{join()}}} 메서드를 이용해서 해당 thread가 일이 끝날 때 까지 기다릴 수 있음.
==== Logging ====
{{{logging}}} 모듈은 다양하고 유연한 로그 기능을 지원. 기본적으로 {{{sys.strerr}}} 으로 출력되며, info와 debug 메시지는 무시된다. 설정을 통해 email, sockets, HTTP server 등으로 보낼 수도 있으며, 메시지 수준에 따라 다른 곳으로 보낼 수도 있다.
* 출력용 메서드들: {{{debug()}}}, {{{info()}}}, {{{warning()}}}, {{{error()}}}, {{{critical()}}}
==== Weak References ====
파이선은 garbage collection({{{gc}}} module로 접근 가능) 을 이용해서 자동으로 메모리를 관리한다. 객체는 더 이상 참조가 되지 않을 경우 gc에 의해 자동으로 정리된다.
하지만, 다른 곳에서 객체를 사용하는 동안에만 객체를 추적하고 싶은 경우 이러한 처리법은 문제가 될 수 있다. 이러한 경우 객체를 참고하기 때문에 gc에 의해 정리가 되지 않기 때문이다. 이럴 경우 {{{weakref}}} 모듈을 사용하면 weakref에 의해 참조가 될 경우에도 gc에 의해 자동으로 정리가 된다.
{{{
>>> a = A(10)
>>> d = weakref.WeakValueDictionary()
>>> d['primary'] = a
}}}
==== 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()}}} 함수 등이 있음.
==== Decimal Floating Point Arithmetic ====
* 실수 연산을 위한 {{{decimal}}} 모듈, {{{Decimal}}} 클래스
* 정확한 진수 표현이 필요한 금융 프로그램이나 기타 등등
* 정밀한 제어
* 중요한 소수 자릿수 계산
* 손으로 한 계산과 결과가 같기를 기대한 계산
* 정확한 반올림이 필요한 계산
* 기본 실수 연산은 binary floating 연산의 한계가 있다 [http://itguru.tistory.com/199 부동소수점에 관한 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
}}}
Contents
- 1. 개요
- 2. 내용
- 3. Data Structures
- 4. Modules
- 5. Input and Output
- 6. Errors and Exceptions
- 7. Classes
- 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
1. 개요 ¶
- https://docs.python.org/3/tutorial의 내용을 열파참/금요일에서 정리.
- 번역이 아닌 정리다보니, 내용의 차이가 있음.
- 번역이 아닌 정리다보니, 내용의 차이가 있음.
- 스터디시만 사용하는 독스: http://goo.gl/11ZcFB
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 문자 필요없음
- 단지 “...” 안의 ‘ 는 허용. ‘...’ 안의 “ 허용. 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을 여러 줄에 걸쳐서 쓸 때 사용하면 유용
- 오직 literals 끼리 적용된다.
>>> 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이랑 동일하게 적용.
- 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.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문에 의해 끝나지 않는 경우 실행이 됨.
- 반복문 안에 있는 break문에 의해 끝나지 않는 경우 실행이 됨.
- try - except ( - finally)문
- try 문 안에서 예외가 발생하지 않을 경우 else 문이 실행 되고, 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.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]
- 그냥 튜플중에 하나짜리 튜블 생성하는 방법
- 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.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.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.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를 생성한다.
다음 세 가지 표현은 모두 같은 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]]
5.1. Fancier Output Formatting ¶
str()
vsrepr()
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.2. Reading and Writing Files ¶
open(filename, mode)
: 파일 열기
- mode
- ‘r’: 읽기 (기본값)
- ‘w’: 쓰기
- ‘a’: 이어쓰기
- ‘r+’,’w+’: 쓰고 읽기
- ‘b’: 바이너리로 열기 (없으면 텍스트로 읽음)
- ‘r’: 읽기 (기본값)
- mode
- binary vs text
- text mode에서는 line ending을 플랫폼에 맞는 형식으로 변환.
- 따라서 text가 아닌 파일을 text 모드로 열면 파일이 변형될 수 있음.
- text mode에서는 line ending을 플랫폼에 맞는 형식으로 변환.
5.2.1. Methods of File Objects ¶
read(size)
- size만큼 파일을 읽는다. size가 지정되지 않거나 음수면 메모리가 허용하는 만큼 읽음.
- 끝에 도달하면 빈 string인 ‘’를 반환
- size만큼 파일을 읽는다. size가 지정되지 않거나 음수면 메모리가 허용하는 만큼 읽음.
readline()
/readlines()
- 한 줄 읽어오는 메소드/한줄씩 묶어서 리스트로 제공하는 메소드
- list(file)로도 readlines와 같은 효과
- 다음과 같이 for문을 이용할 수도 있음:
- 한 줄 읽어오는 메소드/한줄씩 묶어서 리스트로 제공하는 메소드
for line in f: print(line, end=’’)
write(string)
- 파일에 string을 씁니다. string만 가능하니 다른 것을 쓰고 싶다면 str(object)로 변환 후 이용.
- 파일에 string을 씁니다. string만 가능하니 다른 것을 쓰고 싶다면 str(object)로 변환 후 이용.
seek(index,from)
:
- from
- 0 : 파일의 시작점을 기준으로
- 1 : 현재 보고 있는 바이트를 기준으로(tell()로 보이는 그거)
- 2 : 파일의 마지막 바이트를 기준으로
- 0 : 파일의 시작점을 기준으로
- from
tell()
- 파일 내의 현재 지정하고 있는 바이트 위치를 알려줌
- 파일 내의 현재 지정하고 있는 바이트 위치를 알려줌
close()
- 파일을 닫음. 닫고 나서 해당 파일을 쓰려고 하면 오류가 남.
- 파일을 닫음. 닫고 나서 해당 파일을 쓰려고 하면 오류가 남.
closed
- NOT A METHOD
- 닫혔는지 여부를 boolean으로 알려줌
- NOT A METHOD
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.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):
상속 방법
- Exception을 상속받은 Class 들만 가능하다
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문이 실행된 다음에 실행 됨.
- except 문으로 사용자가 지정한 Exception이 아닌 다른 Exception이 발생할 경우 finally 문이 실행된 이후 다시 해당 Exception을 발생시킨다.
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들도 구현이 되어 있음.
- 조금 더 일반적으로 설명하자면, with 구문을 벗어나면 사용된 객체를 자동으로 정리해줌.
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.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
- 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을 통해서도 부를 수 있음.
- iterator object는 다음 element를 return하고, 더이상 element가 없으면
>>> 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.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.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
9.1. Output Formatting ¶
reprlib
모듈
- 긴 object의 출력 결과를 줄여서 출력해줌.
- 긴 object의 출력 결과를 줄여서 출력해줌.
>>> reprlib.repr(set('supercalifragilisticexpialidocious')) "set(['a', 'c', 'd', 'e', 'f', 'g', ...])"
pprint
모듈
- built-in / 사용자가 만든 객체들을 좀 더 읽기 편한 방법으로 출력
- 결과값이 한 줄보다 길 경우 line break와 indentation을 추가
- built-in / 사용자가 만든 객체들을 좀 더 읽기 편한 방법으로 출력
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()함수를 사용
- 이 때는 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에 의해 정리가 되지 않기 때문이다. 이럴 경우
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의 목적으로 사용에 적합.
- 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