1. 파이선(Python) 실전공략
제1막
파이선 프로그래밍을 처음 하는 개발자/운영자를 위한 서바이벌 코딩 공략 노트
(주) 모비젠 ES사업본부
2. 파이선(Python) 프로그래밍 언어는
• 스크립팅 언어이다.
– 펄, PHP, Ruby와 비슷한 격이다. Java/C++보다 훨씬 더 가볍게 사용된다.
– 필요하면 즉석에서 코드를 만드는 기동력을 지향한다.
• 중괄호가 { } 사용되지 않고,
– 들여쓰기(indentation)로 코드 블락을 구분함으로써, 중괄호 열고 닫을 필요가 없다.
– 전체적으로 라인수가 대폭 줄어든다. 대략적으로 닫는 괄호 갯수 만큼 코드가 짧아진다.
• 객체지향형이다.
– 매우 가볍게 객체지향형 프로그래밍이 가능하다.
• Perl과 비교해서
– 깔끔하고 간명하고 우아함을 지향한다. 프로그램에 특수문자 사용이 별로 없다.
• Java와 비교해서
– 단순함을 지향한다. 코드가 너무나도 간단하다.
– 웬만한 실수는 하지 않을 것으로 믿는 어른들을 위한 언어이다.
– 반면, 자바는 개발자들이 어린애 같은 실수를 할 것이라고 가정하기 때문에, 매우 깐깐하게 체크한다.
• 의외로 성능이 좋다.
– Hash(Map)의 성능이 꽤 좋다.
– Integer 연산의 성능만 빼면, 전체적으로 자바/Perl에 밀릴 이유가 없다.
• 파이선 스레딩은 네이티브 스레딩이 아니다.
– 파이선이 가상으로 만든 스레드이다. 그래서 스레드 사이에 충돌없이 변수 공유를 쉽게 할 수 있다.
– 하지만 네이티브 스레드를 꼭 써야 하는 성능이슈가 발생할 경우, 멀티프로세스 방식으로 우회해야 한다.
• 파이선은 문장 끝에, 세미콜론(“;”)을 붙이지 않는다.
3. 파이선(Python) 설치여부를 알아 보기
• 유닉스/리눅스 코맨드
– python 을 실행해 본다.
– 파이선 버전을 알아본다.
$ python
Python 2.5.2 (r252:60911, Nov 23 2011, 17:14:54)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-51)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 파이선 실해하면, 파이선 프롬프트 (>>>)가 뜬다.
• 만약 python이 없으면, 새로 설치해야 한다.
– 설치는 각자 알아서 해 볼 것
4. 최초의 파이선(Python) 스크립트
• 헬로 월드 파이선 프로그램 (1줄 짜리 명령어)
$ python
Python 2.5.2 (r252:60911, Nov 23 2011, 17:14:54)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-51)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> print "Hello, world!"
Hello, world!
>>>
• 스크립트로 만들어서 실행하기
– $ vi hello.py
print "Hello, world!"
– $ python hello.py
– Hello, world!
6. 파이선(Python) 스크립트가 실행이 안될 때
• 퍼미션이 잡혀 있나?
– $ chmod 755 script.py
• 샤뱅(#!) 라인이 제대로 기술되어 있는가? 샤뱅라인은 여러 형태가 존재한다.
– #!/bin/env python
– #!/usr/bin/python
– #!/home/mydir/python/bin/python
• 프로그램 자체에 결함은 없는가?
$ python hello.py
File "hello.py", line 2 라인번호를 알려 준다.
print "Hello, world!".
^
SyntaxError: invalid syntax 에러 종류를 알려준다.
• 들여쓰기(인덴테이션)이 잘 맞지 않는 경우.
– 눈에 안보이는 공백(“ “) 문자와 탭문자(“t”)가 뒤섞여 있을 경우 혼동하기 쉽다.
$ python test.py a b
File "test.py", line 10
print "argv[2]:" + sys.argv[2]
^
IndentationError: unindent does not match any outer indentation level
7. 첫 번째 파이선(Python) 코드
• 아무 인자 없이 실행시킬 경우, Usage를 보여 주는 프로그램
– ./test.py
– Usage: ./test.py input.file output.file
• 이런 식으로 출력하는 프로그램
./test.py
(1) #!/bin/env python
(2) import sys
(3) if __name__ == "__main__":
(4) if len(sys.argv) < 2:
(5) print "Usage: %s input.file output.file" % sys.argv[0]
(6) sys.exit(0)
(7)
(8) print "argv[1]:" + sys.argv[1]
(9) print "argv[2]:" + sys.argv[2]
8. 첫 번째 코드 상세분석
(1) #!/bin/env python
(2) import sys
(3) if __name__ == "__main__":
(4) if len(sys.argv) < 2:
(5) print "Usage: %s input.file output.file" % sys.argv[0]
(6) sys.exit(0)
(7)
(8) print "argv[1]:" + sys.argv[1]
(9) print "argv[2]:" + sys.argv[2]
• 라인(1) 샤뱅라인은 #!/usr/bin/python 이런 식으로도 쓸 수 있다.
• 라인(2) sys 라는 패키지 모듈을 import 한 것이다.
• 라인(3) __name__ 은 파이선에 기본 변수이다. 그게 “__main__” 이면, 해당 스크립트가 최상위에서 호출되었다는 뜻이다.
• 라인(3) if 문의 조건식에는 괄호()가 없어도 된다.
• 라인(3) if 문의 조건식 끝에는 콜론(„:‟)으로 끝난다.
• 라인(3) if 문의 속은 들여쓰기(indentation)로 코드블락의 범위구분을 했다.
• 라인(4) sys.argv는 명령행 인자를 기억하는 어레이형 변수이다.
• 라인(4) sys.argv[0] 는 파이선 스크립트 이름이 온다.
• 라인(4) len()은 어레이를 입력으로 받아서 갯수를 리턴한다.
• 라인(5) print 명령어는 1줄의 텍스트를 출력하고, 끝에 줄내림 “n”이 붙는다.
• 라인(5) 끝에 줄내림을 없애려면, 끝을 콤마(“,”)로 끝내면된다. print “abc”, 이렇게...
• 라인(5) 문자열 포맷 % (변수, 변수) 이런 식으로 포맷 속에 변수 끼워 넣기를 할 수 있다.
• 라인(5) 문자열 포맷 속의 “%s” 는 C언어(Java)와 같은 의미이다. “%d”도 된다.
• 라인(5) sys.argv[0]는 첫번째 인자이며, 이는 호출한 스크립트 명칭 자기자신이다.
• 라인(6) sys.exit(0) 함수는 파이선 실행을 종료한다. 스레드가 동작하고 있어도 무시하고 프로그램 전체를 종료시킨다.
• 라인(7) 한라인 띄어 쓸 때는 띄어 쓴 라인에는 들여쓰기가 적용되지 않는다.
• 라인(8) 문자열을 “+” 연산자로 연결할 수 있다.
9. 파이선(Python) 코드에 한글 사용하기
• 한글 코멘트를 사용한 경우,
• $ python test.py
• File "test.py", line 4
• SyntaxError: Non-ASCII character 'xed' in file test.py on line 4, but no encoding
declared; see http://www.python.org/peps/pep-0263.html for details
• (한글 캐릭터를 받아들이지 않겠다는 오류를 내고 있음)
./test.py
#!/bin/env python
# -*- coding:utf-8 -*- 이 라인을 샤뱅 라인 아래에 넣어 준다.
import sys
if __name__ == "__main__":
# 한글 코멘트도 문제 한글 코멘트를 달았을 때의 오류 해결
if len(sys.argv) < 2:
print "Usage: %s input.file output.file" % sys.argv[0]
sys.exit(0)
print "argv[1]:" + sys.argv[1]
print "argv[2]:" + sys.argv[2]
10. 테스트 코드 실행해 보기
• python test.py sys.argv[0]가 어떻게 달라지는 지 유의할 것.
– Usage: test.py input.file output.file
• python ./test.py
./test.py
#!/bin/env python
– Usage: ./test.py input.file output.file # -*- coding:utf-8 -*-
import sys
if __name__ == "__main__":
• pwd # 한글 코멘트도 문제
if len(sys.argv) < 2:
– /home/iris print "Usage: %s input.file output.file" % sys.argv[0]
sys.exit(0)
• python ~/test.py print "argv[1]:" + sys.argv[1]
– Usage: /home/iris/test.py input.file output.file print "argv[2]:" + sys.argv[2]
• python ./test.py a b
– argv[1]:a
– argv[2]:b
• python ./test.py a
– argv[1]:a 첫번째 인자는 출력!
– Traceback (most recent call last):
– File "test.py", line 10, in <module>
– print "argv[2]:" + sys.argv[2]
– IndexError: list index out of range
– 2번째 인자를 안 줄 경우, sys.argv[2] 를 호출하려고 했다가 Exception이 발생한 경우임.
11. 파이선(Python) 데이터 타입
• 정수형 (int), 실수형 (float), 부울형(bool), 스트링(str) 등이 존재한다.
• 각 타입은 호환이 되는 경우도 있지만 안 되는 경우도 있다. 안될 경우는 타입캐스팅을 호출하자.
$ python
Python 2.5.2 (r252:60911, Nov 23 2011, 17:14:54) [GCC 4.1.2 20080704 (Red Hat 4.1.2-51)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> a = 1 (int) a가 정의된다.
>>> b = 1.6 (float) b가 정의된다.
>>> print a
1
>>> print a+“string“ (int) a 를 “string”과 “+” 하려고 할 때, 오류가 남.
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'str'
>>> print "a:%d b:%d" % (a, b) (float) b 변수가, int 로 캐스팅 된 예
a:1 b:1
>>> print "a:%d b:%f" % (a, b) (float) b를 float로 출력하라
a:1 b:1.600000
>>> print str(a) + "string" (int) a를 스트링으로 변환하여 스트링 연산수행
1string
> >> print a + int("3") (string)”3”을 int 로 변환해서 정수 연산수행
4
>>> c = True True, False는 불린(bool)변수 형이다.
>>> type(c) type() 함수를 호출하면, 해당 변수의 타입을 리턴한다.
<type 'bool'>
12. 파이선(Python)의 정수형
• 파이선의 정수형은 매우 긴 10의 100승 이상의 데이타도 저장할 수 있다.
– Java의 BigInteger 와 같은 특별한 타입과 대응된다.
– >>> j = 1
– >>> for i in xrange(1, 101): 1부터 100까지 곱하라. 100! (팩토리얼)
– j *= i
– >>> print j
– 93326215443944152681699238856266700490715968264381621468592963895217599993
22991560894146397615651828625369792082722375825118521091686400000000000000
0000000000
– >>> print type(j) == type(i)
– False
– >>> print type(j) j는 자동으로 „long‟ 타입으로 바뀌어 있다.
– <type 'long'>
– >>> print type(i)
– <type 'int'>
13. 프로그래밍 기초: 자료구조 / 어레이, 리스트 (1)
• 어레이(Array, 배열)
– 어레이(Array, 배열)은 원소들의 나열형이고, [0], [1], ... 으로 숫자 색인으로 접근한다.
– 어레이(Array)는 갯수가 정해지면, 그 크기를 늘리기 힘들다.
– 어레이(Array)의 특정 위치에 있는 것을 읽는 것, 다시말해 색인 [i] 연산은 매우 빠르다.
수도(pseudo) 코드
a = new array(3) 3개짜리 어레이를 초기화 한다.
a[0] = 1; a[1] = 2;
print a[3] 오류 a[3]은 없다.
• 벡터(Vector), 리스트(List)
– 어레이(Array)의 갯수 제한이 완화된 것이다. 어레이와 거의 유사한 사용 패턴을 보인다.
– 어떤 언어에서는 벡터/리스트와 어레이의 사용법이 거의 같다.
– 대부분의 언어에서는 벡터/리스트에 대해서는, set(), get() 또는 add() 같은 함수를 사용한다.
수도(pseudo) 코드
l = new list() 보통 리스트 생성시 갯수 지정을 하지 않는다.
l.set(0, “a”); l[0] = “a” 와 유사한 패턴
l.set(1, “b”);
l.add(“c”)
b = l.get(1) l[1] 과 유사한 패턴
• 어레이, 리스트, 벡터는 공통적으로
– 순서가 중요한 의미를 갖는다.
– 리스트에 들어간 항목(element)는 데이터타입이 같을 수도 있고 다를 수도 있다.
14. 프로그래밍 기초: 자료구조 / 어레이, 리스트 (2)
• 어레이/리스트에 사용할 수 있는 함수(메소드)들은 다음과 같다. (pseudo code)
– alist = new list() 생성 메소드
– n = alist.size() 갯수 알아보는 메소드, 갯수 n 값을 리턴한다.
– e = alist.get(i) i번째 항목을 가져오는 메소드, “색인으로 검색”한 결과 e 항목을 리턴한다.
– alist.add(z) 맨 끝에 한 항목 z를 추가하기 메소드, alist.size()값이 1 증가한다.
– m = alist.del(i) i번째 항목을 삭제. alist.size()는 1감소. 삭제된 것은 m으로 리턴된다.
– i = alist.indexOf(e) e라는 항목이 들어있는 위치(index)를 찾아내는 메소드.
리턴값 i가 0 또는 양수이면, 해당 위치에 e가 있다는 뜻.
음수 리턴되면, e는 리스트 alist 속에 없다는 뜻이다.
– alist.set(i, x) i번째 위치에, x 라는 항목을 저장한다.
기존에 있는 것에 overwrite된다. alist.size()는 증가하지 않는다.
– alist.insert(i, x) i번째 위치에, x라는 항목을 끼워 넣는다. alist.size()가 1 증가한다.
• 어레이 / 리스트 / 벡터의 일반적인 표기 법은 대괄호 [ ] 를 쓴다.
– array a = [ x, y, z, w ]
– a[0] = x
– a[1] = y
– ...
15. 프로그래밍 기초: 자료구조 / 어레이, 리스트 (3)
• 어레이/리스트/벡터는, 사용하기에 따라서 다음과 같은 변형들을 만들 수 있다.
– 튜플 (tuple) 이라고 함은,
• 리스트이긴 한데, 보통은 갯수가 고정되어 있고, 한번 정의되면 값이 변하지 않는다.
• 개별 항목의 데이터 타입이 다 다를 수 있다.
– 행(row) 이라고 함은,
• DB에서 자주 사용하는 단어이다. 리스트이긴 한데, 개별 항목의 데이터 타입이 각기 다를 수 있다.
• 큐(queue)는
– 리스트(벡터, 어레이)이긴 한데, 보통 뒤에서 추가하고, 꺼내기는 앞에서 꺼낸다.
– First-In-First-Out (FIFO) 라고 할 수 있다.
• 스택(stack)은
– 리스트(벡터, 어레이)이긴 한데, 한쪽에서 밀어 넣고(push), 밀어 넣은 그쪽에서 다시 꺼내고(pop)한다.
– 다른 쪽은 전혀 손대지 않는다.
– Last-In-First-Out(LIFO) 라고 할 수 있다.
• 데크(deque)는 double-ended queue의 약자로서,
– 큐이기는 한데, 큐에 추가 삭제하는 것이, 양쪽 끝에서 자유롭게 하는 경우에 사용한다.
• 큐를 동그란 원형으로 표현하면, circular queue가 되는데,
– 길이가 일정한 원형 큐이며, 넘치면 overwrite되며 기존 데이타는 유실된다.
– 메모리 크기가 일정하게 유지되도록 하는데 사용한다.
– circular queue의 경우, 큐의 head와 tail이 같은 곳을 바라보게 된다.
• 앞 또는 뒤에 항목(element)를 추가하거나 빼내는 연산의 이름은 언어에 따라서 다양하다.
queue (array, list, vector)에 할 수 있는 다양한 연산.
shift() add(), push(), push_back()
unshift(), push_front() pop()
※ 어떤 연산에 최적화 되어 있느냐에 따라서, list/vector/queue/deque/stack이 결정된다.
16. 프로그래밍 기초: 자료구조 / 해쉬, 맵, 집합 (1)
• 해쉬(hash), 맵(map), 딕셔너리(dict)로 언어에 따라 부르는 이름이 다르다.
– 특징은 key => value 형태로 쌍으로 데이터가 정의된다.
– key 는 순서대로 소팅되어 있지 않고, 순서가 엉망인 것이 일반적이다.
• 해쉬(hash 또는 map 또는 dict) 자료 구조는,
– 특정 키(key)를 가지고 value를 찾거나, value값을 저장하는 연산이 매우 빠른 것이 특징이다.
• 해쉬(hash, map, dict)를 traverse 하려면,
– 일반적으로 foreach key (hash.keys()): 형태의 구문을 이용한다.
수도코드(pseudo code)
foreach key in map.keys():
print “key[%s]: val[%s]” % (key, map.get(key))
• 해쉬의 기본연산 (pseudo code)
– h = new hash()
– h.put(key1, val1)
– h.put(key2, val2)
– keys = h.keys() 키들을 모두 가져온다. 결과는 소팅되지 않은 키들의 리스트가 리턴됨.
– values = h.values() 값들을 모두 가져온다.
– val = h.get(key) 특정 키로 값 1개를 가져온다.
– n = h.size() 해쉬에 들어 있는 갯수를 알아낸다.
– if (h.has_key(key)): 해당 해쉬가 키를 가지고 있는지 알아 낸다.
17. 프로그래밍 기초: 자료구조 / 해쉬, 맵, 집합 (2)
• 해쉬(맵, 딕셔너리)의 일반적인 표기법은 다음과 같이, key, value를 쌍으로 묶어서 표현한다.
– hash h = { x => 1, y => 2, z => 6, w => 7 } 또는
– hash h = { x : 1, y : 2, z : 6, w : y } 으로 표기한다.
• 집합(set)은 해쉬와 유사한 성격을 갖는다.
– 집합의 원소들은 순서가 없다. 해쉬의 키에 순서가 없는 것과 유사하다.
– 같은 원소가 집합에 두 번 들어가면, 하나만 남는다. 중복이 허용되지 않는다.
• 해쉬의 키도 그러하다.
• 교집합, 차집합, 합집합, 여집합 등의 연산을 매우 빠르게 할 수 있다.
– 교집합 (intersection)
– 차집합 (difference)
– 합집합 (union)
– 여집합 (complementary)
• 집합(set)은 value가 항상 True인 해쉬로 볼 수 있다.
– set a = { x, y, z, w } ~=
– hash h = { x => True, y => True, z => True, w => True }
18. 프로그래밍 기초: 자료구조 / 해쉬, 맵, 집합 (3)
• 집합(set)의 원소(element)들을 모두 나열하려면, 보통 foreach 구문을 사용한다.
수도코드(pseudo code)
set s = new set()
foreach e in s:
print “element[%s]” % (e)
• 다음과 같이 hash로부터 key_set()을 뽑아내고, 그것을 이용해 traverse하기도 한다.
수도코드(pseudo code)
hash h = new hash()
set keys = h.key_set() 무순의 키집합으로 뽑아낸 경우.
foreach k in keys:
print “k[%s]: v[%s]” % (k, h.get(k))
• 순서만 무작위일 뿐이지, 집합(set)은 사실 어레이나 다름없다. 언어에 따라서는 다음과 같이 쓰기
도 한다. 수도코드(pseudo code)
hash h = new hash()
list keys = h.get_keys() 키를 리스트로 뽑아낼 수도 있다.
foreach k in keys:
print “k[%s]: v[%s]” % (k, h.get(k))
• 개별 언어에 따라 사용방법이 좀 다를 수 있다.
19. 파이선(Python) 튜플 및 리스트
• 튜플은 갯수가 고정된 리스트라고 할 수 있음.
• 파이선의 리스트 및 튜플
– >>> t = (1, 2, 3, 4) # t is the tuple (1, 2, 3, 4) 튜플은 동그란 괄호 ( )
– >>> t2 = 0, 1, 2, 3, 4 # 괄호 없이 튜플을 생성함.
– >>> l = list(t) # l is the list [1, 2, 3, 4] 리스트는 각괄호 [ ]
– # 튜플을 리스트로 바꿈
• 튜플 초기화 방법
>>> empty = () # 공백인 튜플 생성
>>> aTuple = 'hello', # 1개짜리 튜플 만들 때 끝에 콤마!
>>> len(empty)
0
>>> len(aTuple)
1
>>> aTuple
('hello',)
• 튜플을 튜플에 assign 하거나 리스트를 리스트에 assign 할 수 있음.
– t = (0, 1, 2, 3)
– a, b, c, d = t 튜플을 괄호가 생략된 좌항 튜플에 assign한 것임
– [a, b, c, d] = list(t) 튜플을 리스트로 바꾸고, 좌항 리스트에 assign한 것임.
20. 파이선(Python) 딕셔너리(dict)
• 파이선 딕셔너리는 맵 구조체와 같은 것임.
>>> tel = {'jack': 4098, 'sape': 4139} # 키밸류 쌍을 중괄호로 묶어 초기화
>>> tel['guido'] = 4127 # 각괄호 키를 줘서 특정 키를 어레이 인덱스처럼 액세스함
>>> tel # 딕셔너리 전체 내용을 보여 달라.
{'sape': 4139, 'guido': 4127, 'jack': 4098}
>>> tel['jack'] # 특정 키에 해당하는 값을 가져올 때
4098
>>> del tel['sape'] # 특정 키를 삭제할 때
>>> tel['irv'] = 4127
>>> tel
{'guido': 4127, 'irv': 4127, 'jack': 4098}
>>> tel.keys() # 키 리스트를 얻고 싶을 때
['guido', 'irv', 'jack']
>>> tel.has_key('guido') # 특정 키를 가지고 있는지 없는지 검사하고 싶을 때
1
21. 파이선(Python)의 모듈(module)
• 파이선의 모듈은 import 로 읽어들인다.
– import sys # sys 모듈을 import 한다.
– import string # string 모듈을 import 한다.
– import os # os 모듈을 import 한다.
– import re # regular expression 모듈을 import 한다.
– import threading # 스레딩 모듈을 import 한다.
– import time # time 모듈을 import 한다.
• 모듈 속의 변수, 클래스, 메소드 등을 호출하려면, 모듈명을 붙여서 호출한다.
– sys.exit(0)
– os.path.exists(filename)
• 모듈 속의 클래스/메소드를 바로 호출하려면,
– “from 모듈명 import 클래스명/메소드명” 문장을 사용한다.
– “from fibo import *” fibo라는 모듈에서 모든 클래스/메소드/변수를 import 한다.
• 모듈 속의 모든 method, 변수, 클래스 등을 나열해 보려면, dir() 함수를 호출하면 된다.
– import os >>> import os
>>> dir(os)
– dir(os) ['EX_CANTCREAT', 'EX_CONFIG', 'EX_DATAERR', 'EX_IOERR', 'EX_NOHOST', 'EX_NOINPUT',
'EX_NOPERM', 'EX_NOUSER', 'EX_OK', 'EX_OSERR', 'EX_OSFILE', 'EX_PROTOCOL', 'EX_SOFTWARE',
'EX_TEMPFAIL', 'EX_UNAVAILABLE', 'EX_USAGE', 'F_OK', 'NGROUPS_MAX', 'O_APPEND', 'O_CREAT',
'WIFSIGNALED', 'WIFSTOPPED', 'WNOHANG', 'WSTOPSIG', 'WTERMSIG', 'WUNTRACED', 'W_OK',
...
'tcgetpgrp', 'tcsetpgrp', 'tempnam', 'times', 'tmpfile', 'tmpnam', 'ttyname', 'umask',
'uname', 'unlink', 'unsetenv', 'urandom', 'utime', 'wait', 'wait3', 'wait4', 'waitpid',
'walk', 'write']
※ dir() 함수는 도움말을 얻기 위한 매우 훌륭한 도구이다.
22. 파이선(Python) 스트링
• 파이선은 string이라는 기본 타입도 존재하고,
• string이라는 기본 패키지 모듈도 존재한다.
>>> a = "abc“ # 스트링 변수를 하나 선언한다.
>>> dir(a) # 해당 스트링 변수 하나에 적용 가능한 메소드들을 알아본다.
['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__', '__ge__',
'__getattribute__', '__getitem__', '__getnewargs__', '__getslice__', '__gt__', '__hash__',
'__init__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__',
'__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__str__',
'capitalize', 'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs', 'find', 'index',
'isalnum', 'isalpha', 'isdigit', 'islower', 'isspace', 'istitle', 'isupper', 'join', 'ljust',
'lower', 'lstrip', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit',
'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate',
'upper', 'zfill']
>>> import string # string 패키지 모듈을 import한다.
>>> dir(string) # string 패키지 모듈에 들어 있는 메소드 등을 알아본다.
['Template', '_TemplateMetaclass', '__builtins__', '__doc__', '__file__', '__name__', '_float',
'_idmap', '_idmapL', '_int', '_long', '_multimap', '_re', 'ascii_letters', 'ascii_lowercase',
'ascii_uppercase', 'atof', 'atof_error', 'atoi', 'atoi_error', 'atol', 'atol_error',
'capitalize', 'capwords', 'center', 'count', 'digits', 'expandtabs', 'find', 'hexdigits',
'index', 'index_error', 'join', 'joinfields', 'letters', 'ljust', 'lower', 'lowercase', 'lstrip',
'maketrans', 'octdigits', 'printable', 'punctuation', 'replace', 'rfind', 'rindex', 'rjust',
'rsplit', 'rstrip', 'split', 'splitfields', 'strip', 'swapcase', 'translate', 'upper',
'uppercase', 'whitespace', 'zfill']
• s = “abc”
• list = s.split(“ “) 공백으로 잘라서, 리스트로 만든다.
• s.startswith(“a”), s.endswith(“b”) 시작/끝 부분의 스트링 매칭 여부를 알아낸다.
• s.index(“x”), s.find(“y”) 스트링 내에서 어느 위치에 있는지를 알아낸다.
• s.lower() 소문자로 바꾸기, s.upper() 대문자로 바꾸기
• len(s) 길이
23. 파이선(Python)의 if 구문
• 파이선의 if 문은 다음과 같다. if (condition) { 자바코드
// 코드블락
– if condition: } else if (condition) {
– 코드 블락
// 코드 블락
– elif condition:
– 코드 블락 } else {
– else: // 코드 블락
– 코드 블락 }
• condition은 괄호( ) 로 안 묶어 줘도 상관없다.
• condition의 AND, OR는 „and‟, „or‟ 라는 소문자 단어를 사용한다. „&&‟ „||‟ 가 아니다.
• else: 뒤에도 콜론이 온다.
• 코드 블락은 들여쓰기를 해줘야 한다.
• elif 가 else if 문장이다.
24. 파이선(Python)의 for 구문
• 파이선의 for 구문은, 다른 언어의 foreach 구문과 같은 의미를 갖는다.
– for e in list:
– do_something_with(e)
• 다른 언어의 for (i = 0; i < n; i++)에 해당하는 구문은 다음과 같다.
– for i in range(0, n):
– do_something_with(i)
• 만약 n 이 매우 클 경우, range(0, n)을 호출하는 순간 매우 큰 리스트가 생성되어,
메모리 이슈가 발생하므로, 그럴 때에는,
– for i in xrange(0, n):
– do_something_with(i)
• 로 호출하는 것이 바람직하다.
25. 파이선(Python)의 함수 정의
• def 문으로 함수를 정의한다.
– def 함수명(인자, 인자, ...):
– return
– def add(a, b): # a와 b를 더하는 함수임.
– return a + b
• 특정 인자값에 default 값을 부여할 수 있다.
– def call_me(a, b, name = „Allice‟): # name 에 디폴트 값을 할당해 놓은 상태임.
– return name
• 인자의 이름을 부여할 경우, 인자의 순서를 바꿀 수 있다.
– def parrot(voltage, state=„normal‟): 일 경우,
– parrot(state=„zero‟, voltage=1000) 으로 호출가능.
• 인자의 갯수를 무한정 늘릴 수도 있다.
– def fprintf(file, format, *args): # *args에는 몇 개가 올 지 미리 알 수 없다.
– file.write(format % args)
• 람다 함수는, unnamed 함수이다.
– def make_incrementor(n):
– return lambda x, incr=n: x+incr # 이름없는 함수를 람다(lamda)라는 이름으로 부여함.
– def make_incrementor(n): # (수도코드)
– return function(x, incr=n) { return x+incr; } /* 자바스크립트의 함수 정의와 매우 유사하다. */
26. 연습문제
• 텍스트 파일 이름을 명령행 인자로 받아서, 그 파일에 들어 있는 모든 단어에 대해, 단어별 빈도를
카운트해서 출력하는 프로그램을 짜라.
27. 연습문제 답
라인별 설명
(1) #!/bin/env python
(1) 샤뱅 라인 – 인터프리터 명령어를 지정한다.
(2) # -*- coding:utf-8 -*-
(3) (2) UTF-8 한글 코멘트를 가능하게 함
(4) import sys (4) sys 패키지 모듈을 import 함
(5) (6) def count_words(file) 함수 정의. 이 함수는 파일 명을 입력으로
(6) def count_words(file): 받고, (21) words 해쉬를 리턴한다.
(7) words = {} (7) words 해쉬는 초기에 아무것도 없는 {} 것으로 초기화 한다.
(8)
(9) 파일 오픈 하고, 파일 핸들 f를 받아낸다.
(9) f = open(file)
(10) (11) 파일핸들에서 readlines() 함수를 호출하면, 해당 파일의 모든 라인
(11) for line in f.readlines(): 을 리스트 형태로 리턴한다.
(12) tokens = line.strip().split(" ") (11) 리스트로 리턴된 라인에서, 각각의 라인 하나씩을 line이라는 변수로
(13) for token in tokens: 잡아서 처리한다.
(14) if words.has_key(token): (12) line.strip()하면, readlines()에 의해서 읽혀온, 맨 끝의 „n‟
(15) words[token] += 1 을 제거한다.
(16) else: (12) str.split(delimiter, n)의 n은 생략될 수 있다. 스트링을 구분자
(17) words[token] = 1 (delimiter)로 나눠서, 그 결과를 리스트로 리턴한다.
(18)
(19) f.close()
(13) for token in tokens:는 전형적인 foreach 구문이다.
(20) (14) hash.has_key()는 해당 키가 기존 hash에 이미 있는지 없는지를 알
(21) return words 아보는 함수이다.
(22) (15) 키가 이미 있으면, 1증가, (17) 없으면 1 할당.
(23) if __name__ == "__main__": (9), (19) 파일 오픈, 클로즈. 예외처리는 일단 무시함.
(24)
(21) return words는 만들어진 해쉬구조체를 리턴하는 것임.
(25) # 한글 코멘트도 문제
(26) if len(sys.argv) < 2: (23) if __name__ == “__main__”: 은 전형적인 패턴임. 이 프로그램이
(27) print "Usage: %s input.file" % sys.argv[0] 최상위 모듈로 호출되었을 경우... 라는 의미임.
(28) sys.exit(0) (25) 한글 코멘트를 하려면, (2) coding:utf-8이 지정되어 있어야 함.
(29) (26)sys.argv 어레이는 len() 함수로 갯수를 알수 있음.
(30) input_file = sys.argv[1] (27) “format string” % 변수 형태로 포맷 스트링을 지정할 수 있음.
(31)
(32) words = count_words(input_file)
(27) sys.argv[0] 는 파이선 스크립트 명이 들어옴.
(33) (28) sys.exit(0) 는 파이선 프로그램 전체를 종료시킴. 스레드가 동작하
(34) for word in words.keys(): 고 있어도 죽음.
(35) print "word[%s]: %d" % (word, words[word]) (32) cound_words()라는 함수를 호출함.
(34) 카운트 된 words 해쉬 객체에서 키가되는 단어들을 for each 루프로
돌림.
(35) 단어와, 해당 단어의 카운트를 출력함.
(6)/(32) 보통 함수 선언은 사용하는 곳(32)보다 앞에 선언한다.
28. 연습문제
• 텍스트 파일이름을 명령 행 인자로 받는다.
• 해당 파일을 열어서, 홀수 번째 라인의 길이를 다 더한 합을 구하는 프로그램을 짜라.
29. 자바(Java)와 파이선(Python)의 비교 (1)
구분 자바 파이선
타입체킹, 바인 static check, static binding dynamic binding
딩
구문 길이 길고 번잡하다. 짧고 간명하다.
샘플코드 public class HelloWorld { print "Hello, world!"
public static void main (String[] args) {
System.out.println("Hello, world!");
}
}
샘플코드 int myCounter = 0; myCounter = 0
String myString = String.valueOf(myCounter); myString = str(myCounter)
if (myString.equals("0")) ... if myString == "0": ...
샘플코드 // print the integers from 1 to 9 # print the integers from 1 to 9
for (int i = 1; i < 10; i++) { for i in range(1,10):
System.out.println(i); print i
}
클래스/파일 관 일반적으로 개별 클래스가 Java 파일 하나씩 매핑 된다. Python 파일 1개에 여러 클래스를 넣을 수 있다.
계
Exception throw 되는 Exception은 catch 하거나, throws 를 지정해 줄 필요가 없다.
Catch catch 하지 않을 경우, 반드시 throws를 지정해 줘야 한다. catch 할 수는 있다.
파일 I/O import java.io.*; # open an input file
... myFile = open(argFilename)
BufferedReader myFile =
new BufferedReader(
new FileReader(argFilename));
30. 자바(Java)와 파이선(Python)의 비교 (2)
구분 자바 파이선
코드 비교 public class Employee class Employee():
{
private String myEmployeeName; def __init__(self, employeeName,
private int myTaxDeductions = 1; taxDeductions=1, maritalStatus="single"):
private String myMaritalStatus = "single";
self.employeeName = employeeName
//--------- constructor #1 ------------- self.taxDeductions = taxDeductions
public Employee(String EmployeName) self.maritalStatus = maritalStatus
{ ...
this(employeeName, 1);
} 파이선에서는 public/private 구분이 없다.
파이선에서는 생성자가 없다. __init__ 이 사용된다.
//--------- constructor #2 ------------- 파이선에서는 this 대신, self 라는 변수를 사용한다.
public Employee(String EmployeName, int taxDeductions) 인자의 default값 지정을 통해서, 코드를 간명하게
{ 할 수 있다.
this(employeeName, taxDeductions, "single");
}
//--------- constructor #3 -------------
public Employee(String EmployeName,
int taxDeductions,
String maritalStatus)
{
this.employeeName = employeeName;
this.taxDeductions = taxDeductions;
this.maritalStatus = maritalStatus;
}
...
스트링 Trim() s.trim() s.strip()
s.lstrip()
s.rstrip()
31. 자바(Java)와 파이선(Python)의 비교 (3)
구분 자바 파이선
벡터 처리 public Vector aList = new Vector(); aList = []
(타입을 손수 정의) public int aNumber = 5; aNumber = 5
public int anotherNumber; aList.append(aNumber)
anotherNumber = aList[0]
aList.addElement(new Integer(aNumber));
anotherNumber = ((Integer)aList.getElement(0)).intValue(); 변수 타입 정의가 필요 없다.
벡터 처리 public Vector<Integer> aList = new Vector<Integer>; aList = []
(타입을 <>로 지정할 때) public int aNumber = 5; aNumber = 5
public int anotherNumber; aList.append(aNumber)
aList.addElement(aNumber); anotherNumber = aList[0]
anotherNumber = aList.getElement(0);
변수 타입 정의가 필요 없다.
if구문 if ( a > b ) { if a > b :
a = b; a=b
b = c; b=c
}
equality string_a.equals(string_b) string_a == string_b