2011년 11월 19일 토요일

파이썬 이스터에그 antigravity

import antigravity 를치면, 아래와 같은 그림이 나옵니다


http://xkcd.com/353/



Why Python? 이라는 물음에 대한 답입니다.


파이썬 List comprehension

파이썬의 List comprehension은 이걸 또 한글로 번역하면 말이 이상해지기때문에,

그냥 이대로 쓰겠습니다.

파이썬의 고차언어의 특징인 lambda , filter, map, reduce 알고리즘을 리스트로 간단히 구현하는 방법입니다.

보통 람다식을 써서,

a = [1,2,3,4,5] 이중에서 홀수만 골라낸다고 할때

filter (lambda x : x % 2 , a)

이런식으로 씁니다.

또, [1,2,3,4,5]의 리스트를 [2,4,6,8,10]으로 바꾸려면, 다음과 같이 합니다.

map(lambda x : x*2, a) 이런식으로 써줍니다.

그러면 list comprehension은 모냐, 똑같습니다.

[x for x in a if x % 2]
--> [1,3,5] 홀수만 골라내고,

[x*2 for x in a ]
--> [2,4,6,8,10]  두배로 튀겨줍니다.

그러면 람다식으로 하는거랑 리스트 컴프리헨션이 뭐가 다른가 하면,

다른거 없습니다. 똑같습니다.

결과도 똑같고, 사용문법만 조금 다른데,

뭐가 다른가하면 그냥 취향차이입니다.

커뮤니티에서는 그나마 list comprehension이 readable하다는 이유로 , list comprehension을 추천합니다.

이것을 일반적인 형태로 쓰면 아래와 같은데,
[expression for item1 in iterable1 if condition1
                   for item2 in iterable2 if condition2
                   ...
                   for itemN in iterableN if conditionN]


람다식으로 쓰면 훨씬 지저분해지겠죠, 괄호에 괄호가 중첩되는 형태이니,

이 리스트 컴프리헨션식은 for문을 중첩하는 것과 똑같습니다.

그럼 다시, for문이 낫냐, list 컴프리헨션이 낫냐의 문제로 돌아가면,

for문은 C언어부터 자바는 물론 현재도 많이 쓰는 방식이죠,,,

이것의 문제는 문제에 집중할 수 없는게 문제입니다.
if와 for문이 중첩되게 되면, 어디서 부터 끊어야 되는지,
또 차후에 코드를 다시 리뷰할때 이해가 쉽지 않습니다.

그리고, 정말 문제보다 바운더리컨디션에 신경을 많이 써야 됩니다.
그러다보니 그에 대한 반발로 function형 언어들이 나오게 된것이고

이러한 function형 언어는 , 익숙해지면, 정말 좋은 방법중의 하나입니다.

간단한 for문 if문 은 list comprehension으로  하면 됩니다.

남들 열줄쓸거 한두줄로 끝낼 수 있는거죠, 차후에 리뷰도 쉽고요,

C언어계열에서는 잘안쓰는 형태인데,  익숙해지면 정말 좋습니다.



2011년 11월 13일 일요일

파이썬 스레드 threading GIL

파이썬에서는 특이한 GIL이라는게 있습니다.

GIL이란 무엇이냐 하면 Global Interpreter Lock의 약자로 하나의 파이썬 인터프리터에서는 하나의 작업만 실행이 가능한 것입니다.  음 왜냐하면, 하나의 인터프리터가 실행이 될때, global 변수로 제어를 하기때문에, 여러 스레드가 동시에 건드릴 경우, 뒤죽박죽이 되기에, 한번에 하나의 스레드만이 인터프리터 내부 global 변수에 접근가능하도록 해놓은것입니다.

이것이 무슨일을 벌이느냐 하면, 멀티 스레드 프로그램을 짰을 경우 다른 스레드로 들어가기전에 락을 걸어놓고 움직입니다. 그래서,멀티스레드라 할지라도 결국에는
한번에 하나의 스레드가 time sharing하는 형태로 실행이 됩니다.

그래서 결과적으로  멀티코어 CPU라고 하더라도, 스레드를 사용할 경우 그다지 효과가 없고, 오히려 실행시간이 늘어나게 됩니다. 멀티스레드 모듈이 존재하긴 하는데,
이것이 그다지 효과가 없습니다. 그냥 시분할로 돌리는것과 성능이 비슷합니다.
이것이 효과를 보는 경우는 I/O같이  시간을 많이 잡아먹는 경우에는 효과가 있습니다.
I/O 타임에는 CPU가 놀고 있기때문에, 이때는 효과적이지만,
하이퍼스레딩이나, SMT같이 CPU 코어한개안에서 여럿의 프로세스들 돌리는 형태로는
효과를 많이 보지 못합니다.

예를 들면 1부터 200까지 더하는 프로그램을 짠다고 할 경우

1. 하나의 스레드는 처음부터 끝까지 진행

2. 두개의 스레드로 나눠서 하나는 1부터 100까지 더하게 하고,
    다른 하나는 101부터 200까지 더하게 해서 합하는 경우

1번이 무조건 빠르게 됩니다.

2번의 경우 multithread를 쓴다면 효과가 있어야 되는데, 이 GIL때문에 하나의 cpu만을 가지고 진행하기때문에 중간에 Lock을 걸고 풀고하는 비용이 추가가 되어서, 2번이 1번보다 항상 느리게 됩니다.

그래서 이에 대한 해결 방법으로는 multiprocess를 쓰는 방법입니다.

즉, 하나의 interpreter를 쓰는게 아니라 여럿의 프로세서를 구동시키는 것이죠,

이 경우에는 프로세스 관리는 python에서 하는 것이 아니라 os에서 하는 것이기 때문에,
OS에서 적절하게 프로세스를 코어별로 할당을 하게 해서, 전체적으로 스피드를 올려주게 됩니다.

그럼에도 불구하고, 사실 멀티프로세서도 좋은 모델이긴하지만,
아쉬움이 많이 있습니다.

멀티프로세서와 하이퍼 스레딩같이 풀파워로 돌리기는 어렵고,
멀티프로세서를 극대화시키고,
적절하게 I/O bound 한 부분과 CPU bound한 부분을 나누는 것이 중요합니다.

또, 다른 방법은 GIL이 없는 구현, 예를들면, Jython 이나 IronPython을 이용하는 방법도 있긴합니다.  https://wiki.python.org/moin/GlobalInterpreterLock

하지만, 일반적인 job을 하는 경우는 사실 이 상황을 맞닥드리긴 힘듭니다.
파이썬같은 경우는 주로 prototype 에서 가장좋은 효율을 보이기때문에,
이렇게 GIL에 장벽에 가로막히는 일까지 가는 경우가 그렇게 잘 발생하지는 않습니다.

CPU의 모든 성능을 끌어내는 경우는 보통 어떤 일이 완료된다음에 최적화수순을 밟는 경우라서,
이때는 bottleneck을 C로짜는 경우도 있고,
중요한 시스템은 C나 자바로 돌리는게 아직까지는 현실이기때문입니다.

이것 자체는 사실 좋은 주제이기때문에, GIL을 무력화시키려는 시도는 여럿있어 왔습니다만

여러가지 문제가 있어서, 아직까지는 GIL을 유지하는 것으로 가고 있습니다.













2011년 11월 10일 목요일

파이썬 pydev / eclipse 를 이용한 디버깅하기


이번글은 파이썬에서 이클립스를 이용해서 디버깅하는 것을 소개해드리려고 합니다.

원래 python용 debug는 pdb라고 있는데, 이것의 사용법이 gdb를 쓰는 수준이어서,

이것보다는 이클립스에서 사용하는게 좀더 편하기 때문에 이클립스를 기준으로 설명 드리도록 하겠습니다.

여기서는 pydev를 까는거는 pass하도록 하겠습니다. 찾아보시면 간단합니다.

일단 그림을 보시면 아주 간단한 합니다.

적당한 breakpoint를 잡을 수 있게 특정라인에서 더블클릭을 합니다.
그러면 녹색 체크 동그라미가 생기고,

여기서 F11을 이용해서 Debug run을 실행시키면 됩니다.

그게 디버깅을 하기 위한 준비입니다.




그리고나면 Perspective라는 창으로 들어가는데,

아래와 같습니다. 오른쪽 상당에 있는 Pydev와 Debug로 모드를 전환하게되고
Pydev를 누르면 위의 에디터 화면이 나오고, Debug를 누르면 아래와 같은 Perspective화면이 나옵니다.

그리고 Debug는 MS Visual studio랑 비슷합니다. F5-F8을 이용해서,
Step into 부터, 디버깅을 할 수 가 있고요, 오른쪽에 실시간으로, variables가 나옵니다.




일단 이렇게 pydev를 이용해서 debug를 하시면 되고,

실제로는 방법론적으로 breaking point를 잡아서 디버깅하는것도 하나의 방법이지만,
그냥 print 를 찍어서 하는게 더 빠를 경우도 있습니다.

복잡한 프로그램이라면, pydev의 debug를 이용하는게 더 좋을 수도 있고요,
간단한 프로그램이라면, 저런방법 보다도 간단히 log를 찍어서 확인하는 방법이
더 좋을 수도 있습니다.

예를 들면 실시간 환경에서는 저런식의 step debug가 불가능한경우도 있기때문에ㅡ
즉, 디버거의 성능때문이 아니라 어플리케이션의 성질에 따라서, 불가한 경우도 있기때문에,

log를 이용한 방법도 놓치지 않으셨으면 합니다.

또, eclipse를 사용한 방법은 편하긴하지만, 또 보다보면, pdb만 쓰는 환경이 있을 수도 있거든요, 그러니 어느 하나 소홀히 하지말고 쓰시다 보면 좋을 결과가 있을거 같습니다.

이상입니다.







2011년 10월 29일 토요일

Python Extending and Embedding

Extending과 Embedding 말이 비슷하고 이부분 은근히 헷갈립니다.

- Extending :  파이썬에서 C모듈을 불러오는것,

- Embedding : C에서 파이썬 모듈을 불러오는 것,

실제로 인터넷등을 검색하다보면, Extending에 대한 자료는 무척이나 많습니다.

반면에 Embedding에 대한 내용은 상대적으로 빈약합니다.

제가 보기엔 둘다 중요합니다.

파이썬을 쓰다보면, 프로토 타입으로 파이썬으로 작성하고, 속도가 안나오는 부분에 대해서 C로 작성을 한다음에 Extending해서 C모듈을 불러오는 식으로 많이들 쓰시기 때문에, 그렇습니다.

반대로 임베딩의 경우는 되기야되는데, C쪽에서 파이썬 메모리관리를 문제삼아 퍼지는경우도 상당히 많기 때문에, 잘쓰이지도 않고요, 파이썬 인터프리터는 내장하는 방식이라서 덩치고 커지고 해서,  그 내용이 덜한것 같습니다.


이종 언어간의 데이터 전송은 골치아픈점이 상당히 많습니다.
이종 언어간의 I/F를 붙이는 작업을 마샬링이라고 합니다.

정석대로 Extending을 하려면, 함수도 엄청 많고, 번거롭습니다.
그래서 나온 접착모듈들이 있습니다. 기본내장은 ctypes 입니다.

이것을 사용하면, 지저분한 wrapper 작업들을 한큐에 끝내서, 사용할 수가 있습니다.

ctypes 말고도, SWIG이라는 wrapper 전문 패키지도 있고,

SWIG의 경우에는 .i 라는 interface 파일을 따로 작성해야됩니다.

ctypes관련되어서는 따로 페이지를 하나 내어서 설명을 드리도록하겠습니다.

2011년 10월 23일 일요일

[책소개] Python Text Processing by Jeff McNeil


이 책을 소개해 드립니다.

내용이 상당히 많은 부분을 다루고 있고, 텍스트 프로세싱이라는 것이 별거 아닌거 같지만,

제대로 할려면 만만한 부분은 아니라고 생각합니다.

이 책에서 소개하고 있는 내용은 기본적인 I/O핸들링 부터 시작해서,


  • python에서 기본제공하는 라이브러리 사용
  • CSV read/write, json 파일 포맷
  • Regular expression (정규표현식이라고도 하죠)
  • Mark up Language (XML, HTML) handling 
  • 템플릿 (여기서는 mako template을 소개합니다), 
  • 유니코드 , 인코딩. 디코딩
  • 아웃풋 포맷팅(pdf, excel, odf)
  • parsing, NLTK 
이런 주제들을 다루고 있습니다. 

제가 보니깐, 저 위에 나열된 작업들은 보통 일반적으로 끼고 사는 경우가 많습니다. 

시간 소비도 많고요,  위에 있는 아이템만 제대로 하셔도 , 

일찍 퇴근하는데 많은 도움이 됩니다. 

저런것들은 어디서 따로 가르쳐주는데도 없고 하는데, 

정말 내용구성은 좋은거 같습니다. 깊이는 들어가지 않더라도, 한번씩 훑어주므로, 

정작 필요할때는  advanced 하게 들어갈수 있도록 길잡이 역할을 하는 책입니다. 





2011년 9월 12일 월요일

Amazon EC2 django 클라우드

파이썬 django를 올리는 방법은 여러가지가 있는데,

실제로 호스트 업체를 수배해서 서버를 구성해서, django를 올리는 것,

그리고, 구글의 app engine은  구글이 정해놓은 플래폼 위에서, 작성을 하는 것,
장점은 구글은 지저분한 작업을 구글에서 처리를 하고,

실제 작성에만 신경을 쓸 수가 있다.
하지만, 이것은 구글의 플래폼 위에서 작업을 하는 것이기 때문에 ,
그러다보니 아무래도, 한계도 있고,  인터넷으로 자료를 찾아도 그렇게 많지가 않다.
당연히 문제가 생겼을때 트러블 슈팅에도 한계가 있다.

그러던 것이 아마존 EC2를 접해보고선, 놀라지 않을 수 없었다.

이것은 그냥 virtual machine이구나, 물론, 웹 호스팅 업체들이 제공해주던 것을이 있긴 있었는데, 너무나도 간편하게 virtual machine을 사용하는 것을 보고는 정말 이게 진짜 클라우드라는 생각이 들더라,

이미 우리나라에서는 클라우드라는 용어를 일종의 웹하드 비슷하게 사용하고 있어서,

특히, 네이버, 다음의 클라우드 서비스가 그냥 웹하드 서비스 이기때문에,

그냥 클라우드라는 말을 언론에서 접하는 나같은 범주에서는 클라우드는 웹하드 이렇게 인식을 했었는데,

아마존 EC2를 접해보고 나서는 진정 클라우드는 VM 이다라고  말할 수 있다.

그냥 일반 머신은 윈도우를 쓰고 필요한 경우에만, -nix 머신을 사용하는 것이다.
물론 반대의 경우도 마찬가지고,

이것이 앞으로 컴퓨터의 미래가 아닐까 본다,
이미 PC의 성능은 개인이 쓰기는 아까울 정도의 resource가 남아돈다.

그렇다면은, 실제 구동은 클라우드 상에서 돌리고,
PC대신 단말기 터미널정도로만, 해도 충분하지 않을까,

이런게 가능하리라고 예상을 해본다.

지금 모든 머신당 하나의 office 라든지, 프로그램이 깔려있는데
그럴 필요 없이 필요한 경우에만, 그 머신에 들어가서 작업을 하면 된다.

그렇게 되면 놀고 있는 PC라든지, 오피스라든지 이런것이 효율적으로 관리되지 않을까,

대다수의 사람들의 PC에는 과분할정도의 리소스가 돌고 있다 이미
그것을 줄여서 인류혁신에 기여를 하는 것, 이정도 비젼은 있어야지, 클라우드라고 하지.








2011년 8월 22일 월요일

파이썬 클래스 property


파이썬 클래스 중에서 property라는 것에 대해서 살펴보겠습니다.

property는 데코레이터로 들어갑니다.

property는 실제모양을 보면 attribute와 거의 유사하지만,

차이점은 실제 데이터를 access 할때 그 값을 계산을 합니다.


import math
class Rectangle(object):
    
    def __init__(self,r):
        self.r = r
    
    @property
    def area(self):
        return self.r*self.r
    
    @property
    def sqrt(self):
        return self.r*math.sqrt(2)
  
a = Rectangle(4)
    
print a.area  # 16 
print a.sqrt  # 5.65685424949
    
a.area = 1  # AttributeError: can't set attribute
   
        

여기서 보시면 a.r 은 attribute입니다 읽기, 쓰기가 모두 됩니다.
반면에 a.area랑 a.sqrt는 읽기만 되고, 또, 호출할때 그 값을 계산을 합니다.

그래서 이것을 보완 하기 위해서 setter와 deleter에 access가 가능합니다.

원래는 property를 class에 추가하기 위해서 getter, setter, deleter를 추가하던 방식에서
간단히 decorator를 이용한 방식으로 변경이 된것입니다.


2011년 8월 15일 월요일

파이썬 클래스 staticmethod vs classmethod

staticmethod는 C++의 의 그것과 동일합니다.

class는 그냥 이름만 빌려준것이고 일종의 namespace로 함수를 구현하는 것이고

instance에서는 실행되지 않습니다.

아래와 같이 일종의 utility task들을 한쪽에 몰아넣고 쓸데나
class UTIL:
	@staticmethod
	def addtask(a,b):
		return a+b

x = UTIL.addtask(1,4) # x = 5



또는 init구문으로들 많이 사용합니다.

init 구문이 복수개로 들어가는 경우, 일종의 편법으로 생성을 해서 자기자신을 리턴합니다.

아래가 좋은 예제입니다.

import time

class Date(object):
	
	def __init__(self, year, month, day):
		self.year = year
		self.month = month
		self.day = day

	@staticmethod
	def now():
		t = time.localtime()
		return Date(t.tm_year, t.tm_mon, t.tm_day)

# example

a = Date(2011,8,14)
b = Date.now()



classmethod는 인자로 클래스 자기자신을 받게 되어있습니다. 관습적으로 cls라고 표기를 합니다.

그래서 instance에서 호출을 하면, class을 인자로 넘겨주게 됩니다.

class Times(object):

	factor = 1
	@classmethod
	def mul(cls, x):
		return cls.factor*x

class TwoTimes(Times):
	factor =2 
	

x = TwoTimes.mul(4) # Calls Times.mul(TwoTimes, 4) --> 8


이둘은 데코레이터로 구현이 되어있습니다.

2011년 7월 30일 토요일

파이썬 코루틴 (python coroutine) -2

코루틴의 예제, 일단 아래 예제를 보세요
출처는 http://www.dabeaz.com/coroutines/ 입니다.

def coroutine(func):
    
    def start(*args, **kwargs):
        cr = func(*args, **kwargs)
        cr.next()
        return cr
    
    return start


# Example use
if __name__ == '__main__':
    @coroutine
    def grep(pattern):
        print "Looking for %s" % pattern
        while True:
            line = (yield)
            if pattern in line:
                print line,

    g = grep("python")
    # Notice how you don't need a next() call here
    g.send("Yeah, but no, but yeah, but no")
    g.send("A series of tubes")
    g.send("python generators rock!")
        

코루틴을 데코레이터로 선언을 합니다.

이 데코레이터 함수의 역할은 코루틴을 선언할 경우 자동으로 next()를 호출해주는 역할을 합니다.

코루틴의 경우 genertor로 선언을 하고, next()를 호출호출해주어야 준비상태로 들어갑니다.
next()를 호출하는게 필수적이긴 하나 번거로운 일이기 때문에 데코레이터를 써서 처리를 한것이죠

그리고 또 중요한 부분은 ,
yield를 문을 보시면, 뒤에 변수가 없습니다.  이것은 yield를 입력으로 받겠다는 소리입니다.
yield에 변수가 있으면 이것을 출력으로 내보내는데, 위에 구문을 보시면,
yield는 입력으로 받아서 line으로 저장을 하는 것입니다.

g = grep("python")
g.next()
원래는 이랬던 코드가 데코레이터를 사용함으로써
g = grep("python")
이렇게 되었고요,

제네레이터에서 출력을 담당하던 yield 구문이 코루틴에서는 입력을 담당하게 됩니다,

그래서 제네레이터를 producer , 코루틴을 consumer라고 표현을 하는것이죠.

파이썬 제네레이터 (python generator) - next()

이번글은 제네레이터에 대해서 좀 써보겠습니다.



일단 제네레이터는 함수형태로 선언이 되어있어야며,

함수한에 yield 구문이 있어야 generator로 선언이 됩니다.

제네레이터와 이터레이터는 유사하면서도 약간의 차이가 있는데 다음예제를 보시죠..

def countdown(n):
  print 'counting down from %d' % n 
  while n > 0:
     yield n 
     n -= 1
  return 

>>> c = countdown(10)
>>>

>>> c.next() 
Counting down from 10
10
>>> c.next()
9


일단 c로 generator가 생성이 되었습니다.
기본적으로 generator는 next() 를 호출하면 다음 yield가 있는데까지 동작을 하고,
현재 status를 keep 합니다.

그래서 처음 c.next()를 실행시면, 메시지랑 10을 출력하고 멈춥니다.

그리고 다음 c.next()를 호출하면 9를 출력하고 멈춥니다.

언제까지 동작을 하냐 하면, 더이상 yield 구문이 나오지 않을때 ,

그때 raise StopIteration 을 발생시키며, 제네레이터가 멈춥니다.

이것이 제네레이터의 기본적인 동작입니다.

이걸 list처럼 갖다가 쓰면, 똑같이 동작을 합니다.

위에서 선언한 countdown을 그냥 쓰면 다음과 같습니다.
for i in countdown(10):
   print i, 

10 9 8 7 6 5 4 3 2 1 0 

파이썬 데코레이터 (python decorator)

- 파이썬 데코레이터

데코레이터는 한글 이름은 장식자 정도로 번역되는데
이 역시 design pattern에서 나온 이름이고요,

근데 이게 장식자라고 하면 일단 뭔가 감도 잘 안오고 하는데

이 데코레이터의 개념은 일종의 함수 wrapping입니다.

함수를 바깥에서 한번 싸는거죠.




@deco_method
def func1(x):
    return x+1

이런식의 함수가

func1 = deco_method(func1)  

이런식으로 한번 래핑(wrapping)을 해주는 것입니다.


import time

def elapsed_time(functor):
     def decorated(*args, **kwargs):
             start = time.time()
             functor(args, kwargs)
             end = time.time()
             print "Elapsed time: %f" % (end-start)
     return decorated
  

@elapsed_time
def hello():
     print 'hello'
    
보통 이런식으로 많이들 사용합니다. 위의 예제는 하나의 함수가 시간이 얼마나 걸리는지를 재는데 사용하는 예제이고요,

functor가 래핑할 함수이고요,
start, end부분은 전후로 들어갈 부분입니다.

그래서 사용예제들을 보면 디버깅하는데 사용하거나,
-> arg, kwargs를 조사해서, 값을 찍어주는 용도로 쓰기도 하고요

자주사용하는 진입루틴, 출구루틴에 사용을 합니다.

ex ) @login
login이 되어있으면 함수를 실행 아니면, 패스하는 식의 조건을 걸고,
함수를 실행시키는 다던지 하는 용도로 많이 사용을 합니다.


또 데코레이터는 argument를 받을 수도 있습니다.

@deco_method(argument)

이런형태로 쓰여져서 실제로 함수를 wrapping하는 중간에
다른동작도 가능하게 설계가 되어있습니다.



찾아보면 활용법이 많은 방법입니다.
전통적인 언어와는 좀 다르기때문에 헷갈릴수도 있는데 쓰면 쓸수록 장점이 많은 방법입니다.

또 위에서는 함수 데코레이터에 대해서만 얘기를 했는데,
클래스 데코레이터라는게 있습니다.

요것에 대해서는 조만간 또 작성을 해보겠습니다.














파이썬의 중요한 개념 (sequence) - 수열

파이썬에서 가장 중요한 개념이 뭐냐고 물어본다면

저는 이렇게 대답하겠습니다. 집합(set)과 수열(sequence)라고

그이유는 다음과 같습니다. 괜히 중학교, 고등학교 1학년 첫번재 단원이 집합이 있는게 아닙니다.

현대 수학에서 가장 중요한 개념중의 하나가 집합이라는 거죠,

그리고 sequence야 말로, 파이썬의 존재 이유라고 할수 있습니다.

수많은 computer science 연구자이 하려고 했던것은

어떻게 하면 수학을 컴퓨터의 영역으로 끌고 올것인가의 문제였습니다

그래서 C에서 Linked list 부터 시작을 해서 , STL (standard template libarary)
그리고 현대적, C#에 이르기까지 많은 데이터 구조들이
결국엔 수학기호/표현들을 어떻게 구현할까 하는 문제였습니다

수학을 기계적으로 표현할 수 있는가? 에 대해서

최소한 discreate mathmatics에 관해서는 파이썬이 그 하나의 답이 아닐까 봅니다.

파이썬 코루틴 (python coroutine) -1

파이썬과 코루틴

이 개념을 이해하는데 상당히 힘들었습니다. 익숙하지 않은 내용들이 많고,
또 이 개념을 설명해 주는 자료가 그리 많지 않네요

파이썬 2.5부터 지원하는 내용인것 같습니다.

일단 가장 잘 설명해 놓은 자료는 이것 입니다. .

다베아즈 아즈씨의 설명, http://www.dabeaz.com/coroutines/index.html

일단 코루틴은 Lua에서 주로 많이 사용하는 개념으로 보입니다.

여기서 나오는 개념들은 yield, generator, iterator들인데,

이게 다른 언어에서 좀 생소한 개념들이라 좀 헷갈렸습니다.

일단 generator는 producer라고 합니다.
데이터를 생산해 내는 역할을 하죠

이에 반하여 coroutine은 consumer입니다.
데이터를 받아 먹는 역할을 합니다.

여기서 중요한 역할을 하는 구문이 yield입니다.

yield가 2.5 이전 버젼에서는 오직 generator의 구문으로만 쓰였습니다.

이전의 예를 들었던 아래의 구문에서는
def iter_func:
  i =1
  while True:
    yield i 
    i += 1

m  = iter_func()
print m.next()
print m.next()

>> ---------------------
1 
2


yield는 generator구문을 잠시 세우는 역할을 합니다.

위의 구문에서는 일단 generator가 선언된 다음에

next() 를 호출하면, yield가 써진 구문에서 멈추죠.

그리고 다음 next()을 호출하면 다음 yield가 보일때까지 돌다가 멈춥니다.

코루틴도 마찬가지인데
좀 다른것은 제네레이터에서 yield는 마치 return을 대신해서 사용하는 것 처럼 보입니다

코루틴은 이 yield를 입력으로 사용합니다.

자세한 내용은 coroutine -2 에서 이어가도록 하겠습니다.

2011년 2월 6일 일요일

app engine bulk deletor

이전 글에서는 command라인에서 appcfg.py를 이용한 bulk loader를 봤는데

이건 appengine에서 사용할 수 있는 bulkdeletor입니다.

쓰다 보시면, app engine에서 제공하는 데이터관리기에서는 10개단위로 밖에 지울 수 없기 때문에

대용량으로 데이터를 지우고 하려면 아래와 같이 사용하시면 될 거 같습니다.

아래 코드 참고해 주시면 됩니다.

class Bulkdelete(webapp.RequestHandler):
    def get(self):
        self.response.headers['Content-Type'] = 'text/plain'
        try:
            while True:
                q = db.GqlQuery("SELECT __key__ FROM Model")
                assert q.count()
                db.delete(q.fetch(200))
                time.sleep(0.5)
        except Exception,e:
            self.response.out.write(repr(e)+'\n')
            pass

파이썬으로 Yield사용해서 순환수 만들기 (cyclic)

순환수라는 것은 뭐냐하면 1-2-3-4-5-1-2-3-4-5- ....

이렇게 무한하게 도는 수열입니다.

이것을 왜 보여드리냐 하면, 파이썬의 yield을 사용하면

이 순환수가 아주 심플하게 만들 수가 있습니다

def iter_func:
  i =1
  while True:
    yield i 
    i += 1

이렇게 하면됩니다.

그리고서는 다른 함수에서

iter = iter_func() 로 선언하면 iterator로 선언이 됩니다.

그다음에는 iter.next()로 하나씩 꺼내오면 됩니다.

이게 iterator입니다, 반복자라고도 하는데,

고등학교때 배운 무한수열 이런거라고 생각하시면 쉽습니다.

표준 라이브러리의
itertools.cycle과 헷갈릴수도 있는데 itertools.cycle은 무한 반복수열입니다.

generator는 좀 더 customizing이 가능한 수열이죠..

2011년 1월 25일 화요일

remote_shell_spi 사용

GAE에서 기본적으로 data manage panel이 제공이 되지만,

아무래도 대량으로 데이터를 올리고 지우고 하는데는 문제가 있다.

그래서 찾아보니깐, 대량으로 올리고 받는 부분에 있어서는 appcfg.py를 사용하는 방법이 있다.

형식은 excel->csv를 사용하는 쪽이 아무래도 편리하고,

데이터를 올리는 것은 좋았는데 데이터를 한꺼번에 지우는 법에서는 찾아봐야 했다.

방법은 remote_api_shell.py를 사용하는 것인데,

다른 사이트에서 참조하였다.

이것을 하기전에 app.yaml에서 remote_api 사용 가능하도록 수정해줘야한다.

handlers:
- url: /remote_api
  script: $PYTHON_LIB/google/appengine/ext/remote_api/handler.py
  login: admin

그 이후에, remote_shell_api의 사용 방법은
아래와 같이 command line을 띄우고,
remote_shell_api.py yourapp /remote_api

    from models import Entry
    query = Entry.all()
    entries =query.fetch(1000)
    db.delete(entries)

위와 같이 하면 데이터를 대량으로 한꺼번에 지울수가 있다.

2011년 1월 1일 토요일

구글앱엔진 channel API(2)

Channel API의 필수요소

Javascript Client - 자바스크립트 클라이언트는 다음 세가지의 역할을 합니다.

- 채널을 연결할때 서버로 부터 토큰을 받아옵니다.
- 채널에서 날라오는 데이터를 받습니다.
- 원격 클라이언트로 업데이트된 메세지를 보냅니다.

서버 -
- 각각의 자바스크립트 클라이언트와 독립적인 채널을 만듭니다.
- 각각의 자바스크립트 클라이언트에 고유의 토큰을 보냅니다.
- 클라이언트로부터 POST로 올라오는 메시지를 업데이트합니다.
- 업데이트된 메세지를 채널을 통해서 클라이언트들에게 뿌립니다.

클라이언트 ID
- 각각의 자바스크립트 클라이언트를 확인하기 위한 ID입니다.

토큰

채널

메세지

소켓

Google app engine channel (구글 앱엔진 채널)

구글에서 새로 업데이트한 앱엔진 내용중의 channel이다.

channel은 Google서버를 이용해서 persistent한 연결을 만들어준다.

또, 자바스크립트를 사용해서 polling 대신에 callback을 이용해서 시스템에 무리를 주지않고,

실시간으로 메세지를 전달할 수 있다,

협동시스템 collaborate application, multiplayer game, 채팅 등등에서 이용할 수가 있다.

---------> 이 내용은 overview에 있는 내용을 대략적으로 번역한 것인데

위 내용을 보면 polling 대신에 callback이라는 방식을 사용하는 군요,

polling은 시스템을 끊임없이 주기적으로 조사를 해서, 변경사항이 있나를 조사하는 것인데 ,

이 방식은 아무래도 끊임없이 조사를 하다보니깐, 리소스가 많이 들어가고요,

이것을 callback으로 구현을 했나봅니다.


은행의 예를 든다면, polling이라는 것은 번호표가 없고요, 주기적으로 창구에 가서

'제차례인가요' 하고 물어보는 것입니다. callback은 번호표를 받고 기다리고 있으면,

창구에서 'N 번 고객님 오세요' 하고 부르는 것이고요,

아무래도 callback이 resource가 적게 들겠죠, 상대방이 부르기전까지는 자기 할 일을 하고 있으면 되니깐.