본문 바로가기
python

파이썬의 중요 특징(클로저함수, 장식자, 생성기, 코루틴)

by hs_seo 2015. 2. 9.

@클로저함수
함수안에 또다른 함수가 선언되어 반환되는 것을 클로저 함수라고 한다.
- 전역변수를 사용하지 않음
- 내부 데이터의 은닉에 활용

 

<참조>

http://jonnung.blogspot.kr/2014/09/python-easy-closure.html
http://nbviewer.ipython.org/github/jonnung/book-review/blob/master/core_python_study/closure/python_closure.ipynb 

 

 

 

@장식자 - 데코레이터
데코레이터의 개념은 일종의 래핑(wrapping) 함수
실행되는 함수를 파라미터로 받아서 실행되는 함수

 

 

 #!/usr/bin/python
# -*- coding: utf-8 -*-
import time

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

@elapsed_time
def print_hello(*args, **kwargs):
    print "hello"
   
   
print_hello()

 

<참조>

http://pyengine.blogspot.kr/2011/07/python-decorator.html
http://legacy-wiki.dgoon.net/doku.php?id=python:decorator 

 

 

@생성기와 yield

yield 를 이용하여 데이터를 반환
생성 시점에 호출되지 않음
for 문이나 next() 가 호출되었을 때 실제 사용됨
파일읽기등에 사용하면 메모리를 효율적으로 사용할 수 있음

 

 

 def read_in_chunks(file_object, chunk_size=102400):
    while True:
        data = file_object.read(chunk_size)
        if not data:
            break
        yield data

 

f = open(file_url, 'rb')
for line in read_in_chunks(f):
    print line

 

 

@코루틴과 yield

코루틴을 장식자로 선언
장식자는 코루틴을 선언할 경우 자동으로 next 를 호출해주는 역활을 한다.
(코루틴은 선언하고 next()를 호출해 주어야 사용 가능한 상태가 된다. )
yield 를 단독으로 사용하여 데이터를 입력받는 용도로 사용

 

#!/usr/bin/python
# -*- coding: utf-8 -*-
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!")   

 

 

#!/usr/bin/python
# -*- coding: utf-8 -*-
import os
import fnmatch
import gzip, bz2, sys

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

@coroutine
def find_files(target):
    while True:
        topdir, pattern = (yield)
        for path, dirname, filelist in os.walk(topdir):
            for name in filelist:
                if fnmatch.fnmatch(name, pattern):
                    target.send(os.path.join(path, name))

@coroutine
def opener(target):
    while True:
        name = (yield)
       
        if name.endswith(".gz"):
            f = gzip.open(name)
        elif name.endswith(".bz2"):
            f = bz2.BZ2File(name)
        else:
            f = open(name)
           
        target.send(f)
       
@coroutine
def cat(target):
    while True:
        f = (yield)
        for line in f:
            target.send(line)
           
@coroutine
def grep(pattern, target):
    while True:
        line = (yield)
        if pattern in line:
            target.send(line)
           
@coroutine
def printer():
    while True:
        line = (yield)
        sys.stdout.write(line) 

 

 

 

@생성기 표현식

list1 = [ i for i in a]
list2 = ( i for i in a)

 

소괄호를 이용하면 생성기가 됨
for 문 처리 시점에 데이터를 순차적으로 생성함

 

 


반응형