18. 더 많은 것들

지금까지 앞으로 여러분이 사용할 파이썬의 여러 주요한 기능을 살펴봤습니다. 이 장에서는, 여러분이 앞으로 파이썬을 사용하면서 추가로 알아두면 좋을 것을 알려드립니다.


18.1 튜플 넘기기

함수의 실행 결과로 2개 이상의 값을 반환하고 싶은가요? 파이썬에서는 할 수 있습니다. 단순히 튜플을 넘겨주면 됩니다.

>>> def get_error_details():
...     return (2, 'details')
...
>>> errnum, errstr = get_error_details()
>>> errnum
2
>>> errstr
'details') ... >>>


이 코드의 a, b = <계산식>과 같이 하면 계산식의 결과로 넘어온 튜플이 자동으로 두 값에 알맞게 들어갑니다.

이것을 이용하여 두 변수의 값을 바꾸어야 할 때 다음과 같이 할 수 있습니다.

>>> a = 5; b = 8
>>> a, b
(5, 8)
>>> a, b = b, a
>>> a, b
(8, 5)


18.2 특별한 메소드들

클래스에는 init나 del 메소드처럼 특별한 일을 하는 메소드가 있습니다.

이러한 특별한 메소드를 이용하면 파이썬에 내장된 특정 형식들을 흉내낼 수 있습니다. 예를 들어, 여러분이 새로 만든 클래스에서 x[key]와 같은 형태의 인덱싱 연산을 가능하게 하고 싶을 경우 (리스트나 튜플처럼), 클래스에 getitem() 메소드를 구현하면 됩니다. 사실 이것은 파이썬에 내장된 list 클래스에도 똑같은 방식으로 구현되어 있습니다!

다음은 유용한 특별한 메소드입니다. 더 많은 특별한 메소드가 궁금하다면 공식 설명서를 참고하세요.

  • init(self, …​)

이 메소드는 객체가 새로 생성될 때 호출됩니다.


  • del(self)

이 메소드는 객체가 메모리에서 제거되기 직전에 호출됩니다 (그러나 언제 호출될지 분명하지 않으므로 가능하면 사용을 피하세요).


  • str(self)

print 문이라던가 str() 등이 사용될 경우 호출됩니다.


  • lt(self, other)

작음 연산자 (<) 가 사용될 경우 호출됩니다. 이와 비슷하게, 모든 연산자(+, - 등)에 해당하는 특별한 메소드가 하나씩 따로 존재합니다.


  • getitem(self, key)

x[key] 형태의 인덱싱 연산이 사용될 경우 호출됩니다.


  • len(self)

열거형 객체의 길이를 얻어오기 위한 내장 함수 len()이 사용될 경우 호출됩니다.



18.3 한 줄짜리 블록

지금까지 여러분이 작성한 프로그램은 각 블록이 서로 다른 들여쓰기 단계에 따라 구분되어 있었을 것입니다. 그렇지만 한 가지 예외가 있습니다. 다음과 같은 경우죠. 만약 블록에 딱 한 개의 명령만 있는 경우, 특히 조건문이나 반복문을 사용할 때, 그 줄에 해당 명령을 이어서 지정할 수 있습니다. 다음 예제를 보면 이것을 좀 더 명확하게 이해할 수 있을 것입니다.

>>> flag = True
>>> if flag: print 'Yes'
...
Yes


이처럼 한 줄짜리 블록은 새로 블록을 생성하지 않고 그 줄 뒤에 이어서 사용됩니다. 이러한 방식을 사용하면 여러분의 프로그램을 몇 줄 줄일 수 있겠지만, 디버깅 등의 경우가 아니라면 가급적 이 방법을 사용하지 마세요. 그 이유는 적절한 들여쓰기를 사용해야 추가 명령을 넣기 더 쉽기 때문입니다.


18.4 lambda 식

lambda 문은 새 함수 객체를 만들 때 사용됩니다. 기본적으로 lambda 문은 한 줄짜리 수식을 매개 변수로 넘겨 받도록 있는데 이것이 곧 함수의 본체가 되고, 이렇게 생성된 함수를 호출하면 지정한 수식을 통해 계산된 결과값이 반환됩니다.


https://github.com/swaroopch/byte-of-python/blob/master/programs/more_lambda.py

points = [ { 'x' : 2, 'y' : 3 },
           { 'x' : 4, 'y' : 1 } ]
points.sort(key=lambda i : i['y'])
print points
more_lambda.py(이 코드를 more_lambda.py로 저장하세요)

실행 결과는 다음과 같습니다.

$ python more_lambda.py
[{'y': 1, 'x': 4}, {'y': 3, 'x': 2}]


list의 sort 메소드는 key 매개 변수를 받는데, 이것은 어떻게 리스트를 정렬할 것인지를 결정합니다 (주로 오름차순으로 할지, 내림차순으로 할지 정도만 지정하죠). 이 예제에서는 특별히 우리가 정의한 방식대로 정렬을 하려고 하며, 따라서 이 일을 하는 함수를 하나 만들어야 합니다. 그래서 def 블록을 사용하여 함수를 생성하지 않고 lambda 식을 사용하여 새 함수를 그 자리에서 바로 만들었습니다.


18.5 리스트 축약Comprehension

리스트 축약은 이미 존재하는 하나의 리스트를 기반으로 다른 리스트를 생성할 때 사용됩니다. 예를 들어 숫자로 이루어진 리스트가 하나 있고, 이 리스트의 모든 항목에 대해 각 항목이 2보다 클 경우에만 2를 곱한 리스트를 생성하고 가정합시다. 리스트 축약은 이러한 상황에 유용합니다.


https://github.com/swaroopch/byte-of-python/blob/master/programs/more_list_comprehension.py

listone = [2, 3, 4]
listtwo = [2*i for i in listone if i > 2]
print listtwo
more_list_comprehension.py(이 코드를 more_list_comprehension.py로 저장하세요)

실행 결과는 다음과 같습니다.

$ python more_list_comprehension.py
[6, 8]


이 예제에서는 기존 리스트에서 특정 조건(if i > 2)을 만족하는 항목에 대해 2를 곱하는 조작(2*i)을 가한 새 리스트를 생성합니다. 이 때 기존 리스트는 변경되지 않습니다.

리스트 축약을 사용하면 반복문을 사용하여 리스트에 있는 각각의 항목에 접근하고 새 리스트를 생성하는 등의 많은 양의 코드를 한번에 줄여 쓸 수 있습니다.


18.6 함수 인자를 튜플이나 사전 형태로 넘겨받기

`*` 혹은 `**` 을 이용하면 함수의 매개 변수를 튜플이나 사전 형태로 넘겨받을 수 있습니다. 이 방법은 함수의 인자의 개수가 정해지지 않은 함수를 정의하고 싶을 때 유용합니다.

>>> def powersum(power, *args):
...     '''Return the sum of each argument raised to the specified power.'''
...     total = 0
...     for i in args:
...         total += pow(i, power)
...     return total
...
>>> powersum(2, 3, 4)
25
>>> powersum(2, 10)
100


변수 args 앞에 `*` 을 붙이면, 함수로 넘겨진 모든 다른 인수가 args라는 튜플에 담겨진 형태로 함수에 넘어옵니다. `*` 대신 `**` 을 앞에 붙이면, 이번에는 인수가 사전의 형태, 즉 키/값 쌍의 형태로 변환되어 넘어옵니다.


18.7 assert 문

assert 문은 어떤 조건이 참인지 확실하게 짚고 넘어가고 싶을 때 씁니다. 예를 들어, 리스트에 적어도 한 개의 항목이 담겨 있어야 하는데, 그렇지 않아 오류 메시지를 발생시키는 경우 assert 문을 사용합니다. 조건이 참이 아닌 경우, AssertionError가 발생합니다.

>>> mylist = ['item']
>>> assert len(mylist) >= 1
>>> mylist.pop()
'item'
>>> assert len(mylist) >= 1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError


따라서 assert 문은 신중하게 사용하여야 합니다. 보통 이보다는 예외 처리 구문을 작성하여, 즉 문제가 무엇인지 확인하여 사용자에게 오류 메시지를 보여주고 프로그램을 종료하게 하는 게 더 좋습니다.


18.8 데코레이터

데코레이터는 해당 항목을 감싸는 함수의 축약문입니다. 이것은 같은 코드를 '감싸는' 일을 계속 반복해야 할 때 유용합니다. 다음 예제에는 어떤 함수가 실행되는 중에 오류가 발생하면 최대 5번까지 일정 간격을 두고 재실행하는 retry 데코레이터가 있습니다. 또 데코레이터는 여러분이 원격 컴퓨터에 네트워크를 통해 접속을 시도하거나 하는 상황에서도 유용하게 쓰입니다.

from time import sleep
from functools import wraps
import logging
logging.basicConfig()
log = logging.getLogger("retry")


def retry(f):
    @wraps(f)
    def wrapped_f(*args, **kwargs):
        MAX_ATTEMPTS = 5
        for attempt in range(1, MAX_ATTEMPTS + 1):
            try:
                return f(*args, **kwargs)
            except:
                log.exception("Attempt %s/%s failed : %s",
                              attempt,
                              MAX_ATTEMPTS,
                              (args, kwargs))
                sleep(10 * attempt)
        log.critical("All %s attempts failed : %s",
                     MAX_ATTEMPTS,
                     (args, kwargs))
    return wrapped_f


counter = 0


@retry
def save_to_database(arg):
    print "Write to a database or make a network call or etc."
    print "This will be automatically retried if exception is thrown."
    global counter
    counter += 1
    # This will throw an exception in the first call
    # And will work fine in the second call (i.e. a retry)
    if counter < 2:
        raise ValueError(arg)


if __name__ == '__main__':
    save_to_database("Some bad value")

실행 결과는 다음과 같습니다.

$ python more_decorator.py
Write to a database or make a network call or etc.
This will be automatically retried if exception is thrown.
ERROR:retry:Attempt 1/5 failed : (('Some bad value',), {})
Traceback (most recent call last):
  File "more_decorator.py", line 14, in wrapped_f
    return f(*args, **kwargs)
  File "more_decorator.py", line 39, in save_to_database
    raise ValueError(arg)
ValueError: Some bad value
Write to a database or make a network call or etc.
This will be automatically retried if exception is thrown.


동작 원리는 다음을 참고하세요.

18.9 파이썬 2와 3의 차이점

파이썬 2와 3의 차이점은 다음 문서를 참고하기 바랍니다.

18.10 요약

이 장에서는 좀 더 다양한 파이썬의 여러 기능에 대해 살펴봤습니다. 파이썬의 모든 기능을 다 짚고 넘어온 것은 아니지만, 여러분이 실전에서 사용할 수 있을 만큼은 충분히 다루었습니다. 이제 앞으로 무엇을 더 배울지는 앞으로 여러분이 어떤 프로그램을 만들 것인가에 따라 여러분이 직접 선택해야 합니다.

끝으로 파이썬을 더 자세히 알 수 있는 방법을 소개하겠습니다.

지금까지 이 책의 내용을 잘 따라오신 분들이라면 아마 많은 파이썬 프로그램을 작성해 보았을거고, 파이썬이 친숙하고 사용하기도 편할 것입니다. 이 책에서 소개한 예제 프로그램 외에 여러 프로그램을 작성해 보았을 것입니다. 혹시 아니라면, 지금이라도 그렇게 해야 합니다. 자, 이제 남은 질문은 하나입니다. '앞으로 무엇을 더 공부해야 할까요.

다음 문제를 한번 해결해 보시기 바랍니다.


명령줄에서 실행되는 주소록 프로그램을 만들어보세요. 여기에는 친구, 가족, 동료 등을 카테고리별로 나눠 저장하고, 항목을 검색하거나 새로 추가 또는 삭제할 수 있습니다. 각 사람의 메일 주소, 전화번호 등의 정보를 담을 수 있죠. 이러한 정보를 저장했다가 언제든 불러와 사용할 수 있도록 만들어보세요.



지금까지 살펴본 다양한 내용을 다시 되짚어 보면 이 문제를 쉽게 해결할 수 있을 것입니다. 힌트를 원하신다면 다음 꼬리말을 참조02하세요.


02_ 각 사람의 정보를 담는 클래스를 하나 만드세요. 사전을 이용하여 각 사람의 이름을 키로 하여 각 객체를 저장합니다. pickle 모듈을 사용하여 객체를 여러분의 하드 디스크에 저장하세요. 또 사전의 내장 메소드를 이용하여 사람을 추가하고 삭제하거나 수정하는 기능을 구현하세요.



문제를 풀었다면, 여러분은 이제 한 사람의 파이썬 프로그래머라고 해도 손색이 없습니다. 이제 제게 좋은 책을 써서 고맙다는 메일 한 통을 보내주세요 ;-). 또, 이 책의 더 발전할 수 있도록 책을 구입하는 것도 고려해주세요.

이 문제가 너무 쉬웠다면, 다음 문제를 풀어보기 바랍니다.


replace 명령을 직접 구현해 보세요. 이 명령은 주어진 파일들 내부의 특정 문자열을 다른 문자열로 전부 치환하는 데 사용됩니다.


여러분의 의향에 따라 구현은 단순히 문자열을 치환해 주는 식으로 구현했을 수도 있고, 패턴 검색(정규 표현식)을 통해 좀 더 유연하게 구현할 수도 있습니다.


18.11 더 많은 과제

더 많은 문제를 풀고 싶다면 다음 사이트에 주어진 과제를 프로그램으로 직접 구현해 보기 바랍니다.

또, 파이썬 중급 과제 목록도 확인해 보세요.


18.12 예제 코드 읽기

프로그래밍 언어를 배우는 가장 좋은 방법은 코드를 직접 많이 써보고 많이 읽는 것입니다:

  • Python Cookbook은 파이썬을 이용하여 어떤 문제를 해결할 때 유용한 해결 방법과 팁을 정리해 놓은 굉장히 좋은 사이트입니다. 파이썬 사용자라면 반드시 한번쯤 읽어보기 바랍니다.

  • 금주의 파이썬 모듈 또한 한번쯤 읽어야 할 매우 잘 쓰여진 표준 라이브러리 가이드입니다.


18.13 참고 문서

18.14 파이썬 관련 동영상

18.15 질문과 답변

18.16 튜토리얼

18.17 커뮤니티

파이썬을 사용하다가 도저히 해결하지 못할 문제에 직면한 경우, python-tutor list (영문) 혹은 파이썬 마을(한글)에 질문하기 바랍니다.

질문하기 전에 먼저 직접 문제를 해결하려고 노력한 후 질문해야겠죠. (좋은 질문을 하는 방법(영문))


18.18 새로운 소식

파이썬 세계에서 벌어지고 있는 최신 정보를 접하고 싶으면 공식 Python Planet 사이트(영문)을 확인하세요.


18.19 라이브러리 설치하기

파이썬 패키지 목록Python Package Index에 프로그램에서 사용할 수 있는 수많은 오픈 소스 라이브러리가 있습니다.

이 라이브러리는 pip를 이용하면 쉽게 설치하고 사용할 수 있습니다.


18.20 홈페이지 제작

플라스크Flask를 이용하여 홈페이지를 만들 수 있습니다. 다음을 읽어 보세요.

18.21 GUI 프로그램 만들기

파이썬 바인딩을 제공하는 여러 GUIGraphical User Interface 라이브러리를 사용하면 GUI 프로그램을 제작할 수 있습니다. 바인딩이란 C, C++ 혹은 다른 언어로 제작된 라이브러리를 파이썬에서 불러와 사용할 수 있도록 하는 일종의 연결 모듈을 말합니다.

다음은 파이썬에서 사용할 수 있는 GUI 라이브러리 목록입니다.

  • PyGTK

이것은 GNOME을 제작할 때 사용된 GTK+의 파이썬 바인딩입니다. GTK+는 처음에는 사용하기 불편하겠지만 한번 익숙해지면 GUI 프로그램을 빠르게 제작할 수 있습니다. 보통은 Glade라는 디자인 도구를 함께 사용합니다. GTK+를 사용하여 자유/독점 소프트웨어를 만들 수 있습니다. PyGTK 사용법은 PyGTK 튜토리얼을 참고하세요.


  • PyQt

PyQt는 KDE을 제작할 때 사용된 Qt의 파이썬 바인딩입니다. Qt는 Qt Designer라는 디자인 도구와 방대한 문서 덕택에 굉장히 사용이 쉽고 강력한 도구입니다. PyQt는 오픈 소스(GPL 하에서) 소프트웨어를 작성하려고 할 때 무료로 사용할 수 있습니다. 만약 독점 소프트웨어 제작에 쓰려면 사용권을 구입하여야 합니다. 또 Qt 4.5부터는 GPL이 아닌 소프트웨어도 작성할 수 있습니다. PyQt를 사용하시려면 PySide를 읽어 보세요.


  • wxPython

이것은 wxWidgets의 파이썬 바인딩입니다. wxPython은 사용이 조금 어렵기 때문에 익숙해지는 데 조금 시간이 걸릴 수 있습니다. 그러나, wxPython으로 작성된 프로그램은 GNU/Linux, 윈도, 맥OS 등 여러 플랫폼을 지원하며 심지어 임베디드embedded 플랫폼에서도 동작합니다. 또한 SPEStani’s Python Editor나 wxGlade와 같은 IDE 혹은 GUI 디자인 도구를 함께 사용할 수 있습니다. wxPython을 이용하여 독점 소프트웨어 또한 자유롭게 작성이 가능합니다. 자세한 정보는 wxPython 튜토리얼을 확인하세요.


18.22 이밖의 GUI 저작 도구

이밖의 도구에 대해서는 파이썬 공식 사이트의 GuiProgramming 위키 페이지를 참조하세요.

아직까지는 파이썬을 위한 표준 GUI 저작 도구같은 것이 없기 때문에 앞서 소개한 도구 중 여러분의 상황에 맞는 도구를 하나 골라 사용하기를 권합니다. 도구를 선택할 때 가장 먼저 고려해야 할 것은 첫째, GUI 저작 도구를 구입할지 여부입니다. 둘째, 여러분의 프로그램이 윈도 환경이나 맥, 리눅스의 하나에서만 동작해도 되는지 아니면 모든 환경에서 잘 동작해야 하는지입니다. 이때 여러분이 리눅스 환경에서만 동작하면 된다면 현재 KDE를 사용하는지 GNOME을 사용하는지도 고려해야 합니다.

좀 더 상세하고 포괄적인 정보가 필요하다면  'The Python Papers, Volume 3, Issue 1' 의 26페이지를 참조하시기 바랍니다.


18.23 다양한 파이썬 구현

프로그래밍 언어는 크게 두 부분으로 나뉩니다. 하나는 언어고, 다른 하나는 소프트웨어입니다. 여기서 언어란 어떻게 프로그램을 작성하는지 정의해 둔 것을 말하며, 소프트웨어란 이렇게 작성된 프로그램을 실제로 실행시키는 그 무엇을 말합니다.

지금까지 우리는 여러분이 작성한 프로그램을 실행시키기 위해 CPython이라는 소프트웨어를 사용했습니다. 이것은 C 언어로 작성되었기 때문에 CPython이라고 불리우며, 가장 기본적인 파이썬 인터프리터입니다.

이외에도 파이썬 프로그램을 실행할 수 있는 다양한 다른 소프트웨어가 있습니다.

자바 플랫폼 상에서 동작하는 파이썬 구현입니다. 이를 이용하면 파이썬 언어 안에서 자바 라이브러리 및 클래스를 불러와 사용할 수 있으며, 그 반대도 가능합니다.


.NET 플랫폼에서 쓸 수 있는 파이썬 구현입니다. 이를 이용하면 파이썬 언어 안에서 .NET 라이브러리 및 클래스를 불러와 사용할 수 있으며, 그 반대도 가능합니다.


PyPy는 파이썬으로 작성된 파이썬 구현입니다! 이것은 C, Java, C# 등과 같은 정적인 언어를 배제한 동적 언어로 구현된 인터프리터가 어디까지 빨라질 수 있으며 또 얼마나 쉽게 구현할 수 있는지 확인하는 연구 프로젝트입니다.


이외에도 CLPython(Common Lisp 으로 작성된 파이썬 구현)이 있습니다. 또 자바 스크립트 인터프리터 상에서 동작하는 Brython이 있는데, 자바스크립트 대신 파이썬을 이용하여 웹 브라우저 상에서 동작하는 프로그램 ("Ajax")을 제작할 수 있습니다.

이러한 각각의 파이썬 구현은 각 분야에서 유용하게 사용됩니다.


18.24 (고급 프로그래머를 위한) 함수형 프로그래밍

여러분이 큰 프로그램을 제작해야 할 경우, 앞서 객체 지향 프로그래밍 장에서 배웠던 클래스 기반 접근 대신 함수형 접근 방법에 대해서도 공부해야 할 수도 있습니다.

18.25 요약

이제 여러분은 이 책의 마지막에 다다랐습니다. 그러나, 이것은 또 다른 시작일 뿐입니다! 여러분은 이제 열의에 찬 한 명의 파이썬 사용자일 것이며, 파이썬을 이용해 더 많은 문제를 해결할 준비가 되었을 것입니다. 이전에는 생각하지 못했던 여러 자동화 스크립트를 작성하거나, 직접 게임을 만드는 등 여러 시도를 해보기 바랍니다. 자, 이제 시작해 봅시다.



 [ 한빛미디어 파이썬 도서 보러가기]