Wednesday, December 21, 2011

Python Ecosystem - An Introduction (한글)

(원본) http://mirnazim.org/writings/python-ecosystem-introduction/

우선 발 번역임을 알려드리며..
이 틀 동안 일하는 중간중간 쉬는 시간에 한 것이라 대단히 잘 못 된 점이 많습니다.
블로그 글이기 때문에 출판을 위한 번역이라기보단..빨리 읽을 수 있는 것에 초점을 맞췄습니다. :) 이해가 안가는 부분이 있다면 알려주세요. 좀 더 자세하게 번역하도록 하겠습니다. ^_^



PHP, Ruby 혹은 다른 Platform를 다루던 개발자가 Python을 사용하고자 할 때, Python 생태계를 이해하는 것에서 많은 어려움을 느끼게 된다. 개발자들은 가끔 학습서를 원하거나 어떻게 좀 더 표준적인 방법으로 대부분을 해결할 수 있는 설명하는 것을 찾게 된다.

다음은 우리 회사에서 인턴, 훈련생과 다른 Platform에서 Python을 처음 사용하게 된 경력개발자를 위해 쓰여진 Web Application 개발을 위한 Python 생태계 기초 문서에서 발최하였다.

이것은 완벽한 소스가 아니다. 이 문서가 지속적으로 변경 되는 것이 목표이다. 시간이 어느정도 흐르면, 이것은 완벽한 지침서가 되길 희망한다.

예상 독자

이것은 Python 언어 자체를 다루지 않을것이다. 이 지침서는 당신을 Python고수로 마법같이 변화 시켜주지 않을 것이다. 이 글을 읽는 사람은 Python의 기초는 이미 알고 있다고 예상하고 작성 하였다. 만약에 Python을 모르고 있다면, 이 글을 읽기에 앞서  "Zad Show"가 출판한 "Learn Python The Hard Way"를 읽기 바란다.(온라인에서는 무료입니다.)

나는 여러분이 Linux(Ubuntu/Debian과 같은) 혹은 Linux와 유사한 OS를 이용할 것을 원한다. 필자가 가장 잘 아는 것이기 때문이다. 나는 MS Windows와 Mac OS X에서 Cross-browser 확인을 위한 업무 외에는 해 본적이 없다. 만약에 Linux외의 Platform에서 Python을 설치하고자 한다면 다음 문서들을 참고하기 바란다.
당신의 OS에 Python을 설치 하는 가장 좋은 방법은 인터넷을 검색해길 바란다. 개인적으론 Stack Overflow를 가장 권장한다.

버전 설명

참고 요약) Python 2.x는 현재진행 형, Python 3는 빛나는 미래형이다. 만약에 신경 쓰지 않는다면, 다음 Python 설치 부분은 읽지 않아도 된다.
Python으로 시작할 때 3.x 버전을 설치하는 것이 당연한 과정으로 보이겠지만, 실상은 그렇지가 않을 수 있다.

현재 Python은 두 가지 개발버전을 가지고 있다. 하나는 2.7.x이며, 다른 하나는 3.x 이다.(Python 3, Py3K 혹은 Python 3000으로 불린다). Python 3는 Python 2와는 다른 언어라고 볼 수 있다. 미묘하게 다를 때도 있고 완전히 의미가 다른 구문도 존재하고 있다. 지금은 Python2.6 / 2.7이 가장 많이 사용되고 있다. 주류이며 중요한 Package / Framework / Tools / Utilities / Modules 들이 아직 Python 3에 맞게 동작되는 것이 많지 않다.

따라서, 2.x(자세하게 얘기하자면 2.7.x)를 사용하는 것이 안전한 선택이라고 할 수 있다. 만약에 정말로 원하거나, 의미를 완벽히 이했을 경우 Python 3를 선택하라.

Python 3 Wall of Shame 에서 Python 3에 적합한 여러 Packages를 언급하고 있으니, Python 3로 시작하기로 결정하기 전에 읽어보길 바란다.

어떠한 VM을 이용할 것인가?
Python 해석기 혹은 Python 가상머신은 몇 가지 다른 방법으로 구현 되어있다. 이 중에서도 CPython이 가장 많이 사용되고 있으며, 다른 가상머신의 구현에도 참고가 많이 되고 있다.
PyPy는 Python으로 구현되었고, Jython은 Java로 구현 되었으며, Java 가상머신에서 돌아갈 수 있도록 되어있다. 그리고, IronPython 은 Microsoft .Net CLR에서 돌아갈 수 있도록 구현 된 것이다.

하지만, 이것들은 CPython을 정말 사용할 수 없는 경우에만 사용 하는 것이 좋다.

CPython을 사용하지 않는다면, 골치가 아픈 경우가 발생 될 것이다. 이건 날 믿어도 좋다.

Python 설치하기

대다수의 Linux/Unix 배포판과 Mac OS X은 Python이 미리 설치 되어있다. 만약에 그렇지 않거나, 옛날 버전이면 다음 명령어로 2.7.x를 설치 할 수 있다.
Ubuntu/Debian 계열 배포판에서는 다음과 같이 실행 한다.

$ sudo apt-get install python2.7
sudo 는 일반 유저에게 다른 유저(일반적으로 superuser 혹은 root)의 보안 권한을 부여하여 programs를 실행 할 수 있도록 하는 Unix-like OS의 명령어이다. Wikipedia에서 더 자세한 설명을 볼 수 있다.


Fedora/Red Hat 계열에선 다음과 같이 실행한다.

sudo yum install python2.7
RHEL(Red Hat Enterprise Linux)의 경우엔 EPEL repositories에 접근할 수 있어야 정상적으로 설치 할 수 있다.


주의할 점은 앞으로 예제에서 sudo 를 사용하기 때문에 각자의 환경에 맞춰 변경을 해줘야 한다. 

Packages의 이해

처음에 알아두어야 할 점은 Python은 기본적으로 package를 관리하는 도구가 없다는 점이다. 실제로 Python의 package 개념은 상당히 느슨하다.

아마도 알고 있다시피, Python 코드는 modules로 구성이 된다. Module은 단지 1개의 function을 가지고 있는 독립된 한 개의 File일 수도 있고, 한 개 이상의 sub-module을 가지고 있는 Directory일 수도 있다. Package와 module의 차이는 거의 없다고 할 수 있고, 모든 module은 package로 취급 될 수 있다.

그럼, module과 package의 가장 큰 차이는 무엇 일 까? 그것을 알기 위해선 Python이 어떻게 module을 찾는지에 대한 이해가 필요하다.

어떠한 개발환경과 마찬가지로, Python에서도 functions와 classes (strlenException과 같은)는 전역 scope(Python에서는 builtin scope라 불린다)와 다른 것을 포함하기 위해서 사용되는 import statement가 있다. 다음 예제를 보자.

>>> import os

>>> from os.path import basename, dirname
이 Packages는 import statement 에 의해 찾을 수 있는 당신의 Filesystem 의 어딘가에 존재해야 한다. 어떻게 Python은 이 modules들의 위치를 알 수 있을까? 이 위치는 Python 가상머신을 설치할 때 자동적으로 해당 Platform에 맞추어 설치 되었다.

Package들의 위치는 항상 sys.path 에서 알 수 있다. Ubuntu 11.10 Oneric Ocelot가 설치 되어있는 나의 notebook에서는 다음과 같이 보인다.

>>> import sys

>>> print sys.path

['',

 '/usr/lib/python2.7',

 '/usr/lib/python2.7/plat-linux2',

 '/usr/lib/python2.7/lib-tk',

 '/usr/lib/python2.7/lib-old',

 '/usr/lib/python2.7/lib-dynload',

 '/usr/local/lib/python2.7/dist-packages',

 '/usr/lib/python2.7/dist-packages',

 '/usr/lib/python2.7/dist-packages/PIL',

 '/usr/lib/python2.7/dist-packages/gst-0.10',

 '/usr/lib/python2.7/dist-packages/gtk-2.0',

 '/usr/lib/pymodules/python2.7',

 '/usr/lib/python2.7/dist-packages/ubuntu-sso-client',

 '/usr/lib/python2.7/dist-packages/ubuntuone-client',

 '/usr/lib/python2.7/dist-packages/ubuntuone-control-panel',

 '/usr/lib/python2.7/dist-packages/ubuntuone-couch',

 '/usr/lib/python2.7/dist-packages/ubuntuone-installer',

 '/usr/lib/python2.7/dist-packages/ubuntuone-storage-protocol']
이렇게 설치 되어있는 Python의 Directories를 알 수 있다. 최종 단계의 Directory의 이름 순서대로 정렬 됨을 알 수 있다. 이것은 같은 이름의 Packages가 다른 Directories에 있다면 처음 발견 된 곳에서 멈추게 될 것임을 뜻한다.

이미 알아차렸을지 모르겠지만, 이 Package 검색 방식은 당신의 Packages가 먼저 보일 수 있도록 쉽게 변경 할 수 있다. 다음과 같은 방식으로 가능하다. 

>>> sys.path.insert(0, '/path/to/my/packages')
하지만, 이러한 방식은 많은 상황을 발생 시킬 것이고, 너무 쉽게 남용 될 되어 당신을 난폭하게 만들 것이다. 정말로 필요하다면 사용하지만, 남용하진 말자.

site module 은 이러한 package 검색 경로들이 고정되도록 하는 method를 제어한다. 이것은 자동적으로 Python 가상머신들이 초기화 되는 시점에 자동으로 포함 된다. 만약에 이 것에 대해 더 알고 싶다면, 공식문서를 참고하도록 하자.

The PYTHONPATH

PYTHONPATH 는 기본 Package 검색 경로를 확장할 수 있는 환경변수이다. Python에서만 사용되는 PATH 변수라고 생각할 수 있다. sys.path 와는 다르게 : 로 구분된 Python modules를 가지고 있는 Directories의 단순한 리스트이다. 다음 예제를 보자.

export PYTHONPATH=/path/to/some/directory:/path/to/another/directory:/path/to/yet/another/directory
몇 상황에서는 PYTHONPATH 가 덮어씌어지질 않기를 원할 때가 있는데, 그럴 때는 다음과 같이 하면 된다.

export PYTHONPATH=$PYTHONPATH:/path/to/some/directory    # Append

export PYTHONPATH=/path/to/some/directory:$PYTHONPATH    # Prepend
일반적으로 .bashrc.zshrc 와 같은 shell startup 파일에 작성 한다.

PYTHONPATHsys.path.insert 혹은 유사 기술은 해킹이고 일반적으로 일반적으로 이러한 해킹과 멀리하는 것이 좋다. 개인 local 개발환경의 문제를 해결하기 위해서만 사용하지만, 이것이 당신의 제품에 영향을 끼쳐서는 안된다. 같은 효과를 볼 수 있는 더 우아한 방법들이 있으며, 이것에 대해 추후에 알아보도록 하자.

지금은 Python이 어떻게 설치된 Packages를 찾는지 이해하는 것이고, 처음 질문으로 돌아가도록 하자. "Module 과 Package의 차이는 무엇인가?". Package는 한 개 이상의 Module 혹은 Module과 Sub-module의 Collection이다. 또한 일반적으로 1개의 파일로 압축된 형태이며(tarball), 이것은 다음의 내용을 포함하고 있다.
  1. 의존성에 대한 정보
  2. 기본 Package 검색 경로에 파일들을 복제 지시서
  3. Compile 지시서(설치 전에 compile이 필요한 코드가 포함 되어있다면)

이것이 전부다.

외부 Packages

본격적으로 Python으로 개발을 하기 위해선 다양한 작업을 하기 위한 외부 Packages를 설치해야 한다.

Linux System에서 외부 Packages를 설치하기 위한 최소 3가지 방법이 존재한다.

  1. 배포본에서 제공하는 Package 관리 시스템을 이용한다.(deb,rpm 같은)
  2. 다양한 community-developed 도구를 사용한다. pipeasy_install
  3. Source files를 이용해 설치한다.
이 3가지 방법은 같은 목적을 달성할 수 있다. 이것은 독립적으로 설치 되고, 필요하다면 compile을 하며, 표준 Package 검색 위치에 modules를 위치 시킨다.

2,3번은 OS환경에 영향이 거의 없이 같이 동작될 것이다. 다른 방법으로 외부 Package를 설치하고자 한다면, Stack Overflow 에서 알아보도록 하자.

외부 Package는 어디서 찾는가

외부 Packages를 설치하기에 앞서 어디선가 찾아야 한다. 다음과 같은 방법들이 있다.
  1. 배포본에서 제공하는 Package 관리 시스템.
  2. Python Package Index (or PyPI)
  3. LaunchpadGitHubBitBucket 와 같은 다양한 Source Code 호스팅
배포본의 Package 관리 시스템으로 설치하기


배포본의 Package 관리 시스템으로 설치하는 것은 간단한 명령어 혹은 GUI app을 사용한다.예를 들어 simplejson(a JSON parsing utility)을 Ubuntu 시스템에서 설치하고자 한다면 다음과 같은 명령어를 친다. 

$ sudo apt-get install python-simplejson

pip를 이용하여 설치하기

easy_install 는 거의 인기를 잃었다.easy_install 를 대체하기 위해 나온 pip 에 집중하도록하자.
pip(Python Package Index) 는 Python packages를 설치하고 관리하기위한 툴이다. pip 는 Python 가상머신과 함께 설치 되지 않으므로, 먼저 설치하는 과정이 필요하다. Linux에서는 일반적으로 다음과 같이 설치 한다.

$ sudo apt-get install python-pip
다른 Package를 설치하기에 앞서 항상 pip 를 최신버전으로 유지를 한다. Ubuntu repositories에 있는 PyPI는 일반적인 PyPI보다 늦기 때문이다. pip를 이용하여 pip 를 업그레이드 한다.

$ sudo pip install pip --upgrade
지금 부터 Python의 Package를 설치하기 위해선 다음 명령어 패턴을 이용한다.
pip install package-name. 그럼 simplejson 를 설치하기 위해선 다음과 같다.

$ sudo pip install simplejson


Package 삭제는 쉽다.

$ sudo pip uninstall simplejson
기본적으로 pip 는 PyPI의 가장 최신 안정 버전을 설치할 것이다. 그러나 가끔 프로젝트 상황에 따라, 정확한 버전의 Package를 설치해야 하는 상황이 있다. 그럴 때는 다음과 같이 실행 한다.

$ sudo pip install simplejson==2.2.1
가끔은 업그레이드,다운그레이드 혹은 재설치를 해야하는 경우가 있는데, 그럴 때는 다음과 같이 실행한다.

$ sudo pip install simplejson --upgrade         # Upgrade a package to the latest version from PyPI

$ sudo pip install simplejson==2.2.1 --upgrade  # Upgrade/downgrade a package to a given version
이번엔, 버전관리 repository에는 있으나 PyPI에는 배포가 안된 Pacakge를 설치하기 위해선 어떻게 해야 할까? pip 는 이것이 가능하다. 하지만, 그전에 버전 관리 시스템이 설치되어있어야 한다. Ubuntu 에서는 다음과 같이 설치를 한다.

$ sudo apt-get install git-core mercurial subversion
버전 관리 시스템을 설치한 후에는, 다음과 같이 버전 관리 repository에서 Package를 설치 할 수 있다.

$ sudo pip install git+http://hostname_or_ip/path/to/git-repo#egg=packagename

$ sudo pip install hg+http://hostname_or_ip/path/to/hg-repo#egg=packagename

$ sudo pip install svn+http://hostname_or_ip/path/to/svn-repo#egg=packagename
다음과 같은 방법으로 쉽게 같은 위치에 repository로 부터 설치를 할 수가 있다. Filesystem path에 3개의 slash를 사용한다.

$ sudo pip install git+file:///path/to/local/repository
git Protocol을 이용할 때 주의해야 할 점이 있다. 다음과 같이 git+git 를 써야한다.

$ sudo pip install git+git://hostname_or_ip/path/to/git-repo#egg=packagename
이 eggs 로 부터 무엇이 일어나는 것인지 궁금해할 것이다. 지금 부터 Package source와 metadata를 가지고 있는 압축된 Python Package에 대한 이해를 하도록 하자. pip 는 Package를 설치하기 전에 egg정보를 만든다. Code 저장소에서 setup.py 를 열어보면 egg의 이름을 알 수가 있다.(대부분 거기에 있다). setup 섹션을 찾아보면, name="something" 와 같은 줄을 찾을 수 있을 것이다. 다음은 simplejson의 setup.py 에서 가져온 Code 조각이다. 

setup(

    name="simplejson", # <--- This is your egg name

    version=VERSION,

    description=DESCRIPTION,

    long_description=LONG_DESCRIPTION,

    classifiers=CLASSIFIERS,

    author="Bob Ippolito",

    author_email="bob@redivi.com",

    url="http://github.com/simplejson/simplejson",

    license="MIT License",

    packages=['simplejson', 'simplejson.tests'],

    platforms=['any'],

    **kw)
만약에 setup.py 이 없어서 egg 이름을 어떻게 찾는가에 대해서 고민 할 필요는 없다. Package Source를 Project Directory에 넣고 import 하고 당신의 Code인 것처럼 사용하면 된다.

The --user switch

앞선 예제들은 모두 System 전반적으로 사용되는 Packages를 설치하는것이다. 만약에 pip install 에 --user 옵션을 사용한다면 Packages 는 당신의 ~/.local Directory에 설치 될 것이다. 예를 들면 다음과 같다.

$ pip install --user markdown2

Downloading/unpacking markdown2

  Downloading markdown2-1.0.1.19.zip (130Kb): 130Kb downloaded

  Running setup.py egg_info for package markdown2



Installing collected packages: markdown2

  Running setup.py install for markdown2

    warning: build_py: byte-compiling is disabled, skipping.



    changing mode of build/scripts-2.7/markdown2 from 664 to 775

    warning: install_lib: byte-compiling is disabled, skipping.





    changing mode of /home/mir/.local/bin/markdown2 to 775

Successfully installed markdown2

Cleaning up...
markdown2 Pacakge가 /home/mir/.local/bin/markdown2 에 설치 되었다.

모든 Package가 System 전반적으로 설치 되지 않기를 원하는 이유는 몇 가지가 있다. 각 Project 별 분리되고 독립된 Python 환경을 꾸미는 것을 보여줄 때는 이것에 대한 설명을 건너띄도록 하겠다.

Source로 부터 설치하기

Source로 부터 설치하기 위해선 1줄의 명령어만 필요하다. 압축이 풀린 Package가 있는 Directory에서 다음 명령어를 실행 시켜준다.

cd /path/to/package/directory

python setup.py install
비록 이 방법을 할 줄 알더라도, pip 방법을 이해하는 것을 추천한다. 왜냐면, 업그레이드/다운그레이드 등의 Package를 관리하는 방법을 수동으로 다운로드 하고 압축을 풀고 설치를 하는 작업 없이 쉽게 실행 할 수 있기 때문이다. 모든 방법을 실행해보고도 안될 때 최후의 선택으로 Source로 설치하기를 하길 바란다.

Compiling이 필요한 Package 설치하기

우리는 Package를 설치하기 위한 거의 모든 방법을 알았다. 하지만, 부족한 하나가 있다. 그것은 설치하고 사용하기 위해선 Compile이 필요한 C/C++  code를 가지고 있는 Python Package이다. Database Adapter 혹은 Image Processing Library등의 Package가 좋은 예이다.

pip가 source를 관리할 수 있지만, 개인적으론 배포본 Package 관리 시스템을 통해 설치하기를 선호한다.


만약에 pip 로 설치하고 싶다면, Ubuntu 의 경우엔 다음과 같이 하자.


Compiler와 관련 Tools을 설치하자.

$ sudo apt-get install build-essential
Python 개발 파일을 설치하자.(header와 같은)

$ sudo aptitude install python-dev-all
만약에 python-dev-all 의 배포본을 찾을 수 없다면, python-devpython2.X-dev 등을 찾아보도록 하자.


PostgreSQL adapater Package 인 psycopg2 을 설치하자고 가정하면, PostgreSQL의 개발 파일들도 필요하게 된다.

$ sudo aptitude install  postgresql-server-dev-all
이러한 관련된 작업들이 완료 되면,이제 pip install 실행 할 수 있다.

$ sudo pip install psycopg2
모든 Pacakge들이 pip 설치법에 호환이 되지 않을 수 있다는 점을 잊지 말자. Source를 compiling 하는 것이 편하거나, 당신의 Platform에서 필요한 경험과 이해가 있다면 그대로 진행 하면 된다.

개발환경

대부분의 개발 커뮤니티에서 한 가지 이상의 다른 사람들도 받아들일 만한 설정 방법을 제안하고 있음에도 자신이 좋아하는 방법으로 개발환경을 꾸미길 선호한다. 큰 문제가 없다면, 일반적으로 많이 사용되고, 실험 된 방법으로 설치하는 것이 좋다.(그냥 우선 이렇게 번역-_-;)

virtualenv

Python 개발환경으로 가장 유명한 것은 Virtualenv Package 이다. Virtualenv 는 독립된 Python 개발환경을 만들어 준다. 여기서 나올만한 질문 : 왜 독립된 Python환경이 필요하나요? 대답은 Virtualenv의 문서를 인용하도록 하겠다.

근본적인 해결을 위한 방법은 독립과 버전들 간접적인 권한이다. Libfoo 의 Version 1에서 필요하지만, Version 2는 필요하지 않는 App을 상상해보라. 어떻게 이 App들을 둘 다 이용 할 것인가? 만약에 못든 것을 /usr/lib/python2.7/site-packages 에 설치한다면, 업그레이드 하지 말아야 하는 App도 업그레이드가 되어버리는 상황에 마주칠 것이다.

간단히 말하자면, 각 Project 별로 독립적인 Python 환경을 가질 수 있다는 것이고, 각각의 독립된 환경에 필요한 Packages를 설치하게 될 것이다.


그럼 pip 를 이용하여 virtualenv 를 설치하자. 

$ sudo pip install virtualenv
Virtualenv를 설치하고, 다음 명령어를 내려 Project를 위한 독립된 Python 환경을 만들어 보자.

$ mkdir my_project_venv

$ virtualenv --distribute my_project_venv

# The output will something like:

New python executable in my_project_venv/bin/python

Installing distribute.............................................done.

Installing pip.....................done.

무슨일이 일어났는가? 독립된 Python환경을 가지는 my_project_venv Directory가 생성이 되었다. --distribute 옵션은 virtualenv가 setuptools 에서 구 시스템에 의거하여 distribute package 에 기반 되어 새롭게 사용 되게 해준다.(말이 되게 이상한데, 기존 시스템을 가지고 새롭게 독립적인 공간을 만들어준다는 뜻으로 보입니다.) --distribute 옵션은 pip 도 자동적으로 새로운 가상공간에 설치해주므로, 사용자가 직접 해야 할 것은 없다는 것을 이해하길 바란다.

My_project_venv directory 를 살펴보도록 하자. 다음과 같은 구조를 발견 할 수 있을 것이다.

# Showing only files/directories relevant to the discussion at hand

.

|-- bin

|   |-- activate  # <-- Activates this virtualenv

|   |-- pip       # <-- pip specific to this virtualenv

|   `-- python    # <-- A copy of python interpreter

`-- lib

    `-- python2.7 # <-- This is where all new packages will go

다음 명령으로 virtualenv 를 활성화 시켜보자.

$ cd my_project_venv

$ source bin/activate
activate script 가 보여진 후, 다음과 같은 Prompt 를 볼 수 있을 것이다.

(my_project_venv)$ # the virtualenv name prepended to the prompt
다음 명령으로 virtualenv 를 비활성화 할 수 있다.

(my_project_venv)$ deactivate
다음 명령으로 시스템에 설치된 환경과 다름을 아는데 좀 더 도움이 될 것이다.(virtualenv가 활성화 되어있다면, 비활성화 시켜라)
처음으로 python/pip 명령어가 어디에 있는지 알아보도록 하자.

$ which python

/usr/bin/python

$ which pip

/usr/local/bin/pip
which 명령어는 Wikipedia에서 보도록 하자.


그럼 다시 virtualenv를 활성화 시키고 어떻게 다른지 살펴보자.

$ cd my_project_venv

$ source bin/activate

(my_project_venv)$ which python

/home/mir/my_project_venv/bin/python

(my_project_venv)$ which pip

/home/mir/my_project_venv/bin/pip

virtualenv 가 하는 것은 Python 실행 환경을 복제하고, utility script를 생성하며, 설치하고 업그레이드하며 삭제하는 모든 Project 주기를 관장하는 공간을 생성한다. 또한,
1) 사용자가 Package를 설치할 때, 활성화된 virtualenv 공간에만 영향을 끼칠 수 있도록하는,
2) 현재 활성화 된 virtualenv 공간과 시스템 전반적인 곳에서 import 가 가능하도록 하는, Package 검색 경로와 PYTHONPATH 에 대한 마법을 부린다.

중요한 점은 시스템 전반적으로 설치된 Python의 Package는 virtualenv에서도 사용이 가능하다는 것이다. 그 뜻은 만약에 시스템 전반적으로 영향을 받도록 simplejson Package를 설치했다면, virtualenvs에서도 이것을 사용할 수 있다는 것이다. 이러한 것은 --no-site-packages 옵션으로 끌 수 있다.

$ virtualenv my_project_venv --no-site-packages

virtualenvwrapper

virtualenvwrapper 는 virtualenv 에서 제공 되는 Create/Activate / Manage / Destory를 좀 더 쉽게 하는 Utilities를 제공한다. virtualenvwrapper 를 설치하기 위해서 다음과 같은 명령어를 이용한다.

$ sudo pip install virtualenvwrapper
설치 한 후에, 다음과 같은 설정이 필요하다.

if [ `id -u` != '0' ]; then

  export VIRTUALENV_USE_DISTRIBUTE=1        # <-- Always use pip/distribute

  export WORKON_HOME=$HOME/.virtualenvs       # <-- Where all virtualenvs will be stored

  source /usr/local/bin/virtualenvwrapper.sh

  export PIP_VIRTUALENV_BASE=$WORKON_HOME

  export PIP_RESPECT_VIRTUALENV=true

fi
WORKON_HOME 과 source /usr/local/bin/virtualenvwrapper.sh 만 설정시 필요하며, 나머지 부분은 개인 환경을 따른다.


위의 환경을 ~/.bashrc 에 위치하기 위해서 다음과 같은 명령을 실행한다.

$ source ~/.bashrc


Shell 창을 모두 닫아서 열거나, Tab을 열게 된다면 ~/.bashrc 가 실행 되어 virtualenvwrapper 설정이 자동으로 적용되어 같은 효과를 기대할 수 있다. 

다음 명령어들을 실행하여, virtualenv 을 create/activate/deactivate/delete 해보자.

$ mkvirtualenv my_project_venv

$ workon my_project_venv

$ deactivate

$ rmvirtualenv my_project_venv
Tab-based bash shell 에서도 virtualenvwrapper 가 잘 호환 된다.
virtualenvwrapper 홈페이지로 가서 더 많은 명령어와 설정 옵션을 보도록 하자.

PIP와 Virtualevn를 이용한 기본 연계 관리

virtualenv 에 pip 를 연결하여 Project를 위한 간단한 연계 관리 도구를 만들 수 있다.


pip freeze 명령어를 이용하여 현재 설치되어있는 Package 리스트를 볼 수 있다. 예를 들어 이 블로그를 만들기 위해 사용된 Python Packages를 보도록 하자.

$ pip freeze -l 

Jinja2==2.6

PyYAML==3.10

Pygments==1.4

distribute==0.6.19

markdown2==1.0.1.19
-l 옵션은 pip 명령어에서 현재 활성화된 가상공간에서 설치 된 것만 보여줄 수 있도록 하는 것이다.


이렇게 뽑힌 리스트를 파일로 저장하고, 버전관리 시스템에 추가 할 수 있다.

$ pip freeze -l  > requirements.txt


pip freeze 의 결과물을 가진 파일로 부터 새로 설치가 가능하다.

$ pip install -r requirements.txt

기타 중요 도구들

VMs 와 Package 관리 등의 Python 버전의 기초를 보았다.
대부분이 Web apps 개발자에게 맞춰진 도구들임을 양해 바란다.

편집기

Python을 작성하기 위한 정말 많은 좋은 편집기들이 있다. 개인적으론 Vim을 선호하고, 편집기 전쟁에 뛰어 들고 싶지 않다. - 나중엔 모르겠지만... ;)
Python을 지원하는 편집기와 IDEs는 다음과 같다. Vim/Gvim, Emacs, GEdit for GNOME, Kate for KDE, Scribes, Komodo Edit/IDE from ActiveState, Wing IDE from WingWare, PyCharm from JetBrains, PyDEV for Eclipse. 다른 것들 도 많이 있지만, 이것 들이 유명한 것들이다. 이 중 당신에게 적합한 것을 고르면 된다.

Pyflakes: Source checking and linting

Pyflakes 는 File의 Text를 분석해 Python source의 에러를 검사해주는 간단한 프로그램이다. 문법과 간단한 로직 에러, 그리고 사용되지 않는 module이 import 되었는지, 사용이 한번 밖에 안되는 변수들이 있는지 정도를 검사 해준다.
pip 를 이용하여 설치해보자.

$ pip install pyflakes
Terminal 상에서 Python source file을 불러낼 수 있다. 다음을 보자.

$ pyflakes filename.py
Pyflakes 는 사용하고 있는 편집기에서도 사용 할 수 있다. Vim 에서 어떻게 보여지는지 볼 수 있다.
PyFlakes
사용하고 있는 편집기에서 Pyflakes를 어떻게 연동 할 수 있는지는 Stack Overflow에서 알아보도록 하자.

Requests: HTTP library for human beings

Requests 는 HTTP를 컨트롤 할 수 있는 Library이다.
다음과 같이 pip 를 이용하여 설치한다.

$ pip install requests
이번엔 예제를 보도록 하자.

>>> import requests

>>> r = requests.get('https://api.github.com', auth=('user', 'pass'))

>>> r.status_code

204

>>> r.headers['content-type']

'application/json'

>>> r.content

...

Flask: Microframework for web development

Flask 는 Python을 위한 Werkzeug와 Jinja2를 기본으로 하는 작은 Framework이다.
이 또한 pip 를 이용하여 설치한다.

$ pip install Flask
사용예제는 다음과 같다.

from flask import Flask

app = Flask(__name__)



@app.route("/")

def hello():

    return "Hello World!"



if __name__ == "__main__":

    app.run()
그리고 실행은 다음과 같이 실행한다.

$ python hello.py

 * Running on http://localhost:5000/

Django: Full stack framework for web development

Django는 모든 것을 갖추고 있는 Web Framework이다. ORM, HTTP library, form handling, XSS filtering, 그리고 templating 는 물론이고 다른 것들도 지원하고 있다.
다음과 같이 pip 를 이용하여 설치한다.

$ pip install Django
Django website 로 가서 문서를 따라해보며 익혀보도록 하자. 상당히 쉽다.

Fabric: Streamline the use of SSH for deployment and/or system admin tasks

Fabric 은 Python Library이며 SSH을 이용하는 app이나 system administration 작업을 실행 할 수 있는 command-line 도구이다.
Local은 물론이고 Remote Shell상에서 실행 할 수 있으며(일반적으로 sudo를 이용하여), Files를 uploading/downloading 도 가능하다. 또한 사용자 입력을 받을 수 있으며, 실행을 취소 할 수도 있다.
pip 를 이용하여 설치 할 수 있다.

$ pip install fabric
간단히 Fabric 작업을 작성해보자.

from fabric.api import run



def host_type():

    run('uname -s')
그 후 실행은 어떻게 되는지 확인 해보자.

$ fab -H localhost host_type

[localhost] run: uname -s

[localhost] out: Linux



Done.

Disconnecting from localhost... done.

SciPy: tools for scientific computing with Python

만약에 과학적이나 수학적인 계산을 해야 하는 경우 SciPy가 필요한 도구일 것이다.
From SciPy website:
SciPy 사이트에서 발췌한 글이다.
SciPy ("Sigh Pie"라고 읽는다.)는 수학, 과학, 공학을 위한 Open-source 소프트웨어이다. 그리고, 이것은 매우 유명한 컨퍼런스인 scientific programming with Python 이름이다. SciPy Library는 편리하고 빠른 N-dimensional array를 조작가능하게 하는 NumPy에 의존성이 있다. SciPy Library는 NumPy arrays를 가지고 동작 되고, 많은 사용자에게 익숙하고 효과적인 수치적 통합 및 최적화를 위한 루틴을 제공한다. 또한, 거의 유명한 OS에서 동작이 되며, 빠르게 설치된다. 그리고 무료다. NumPy과 SciPy 는 사용하기 쉽지만 세계적인 과학자와 공학자들에게도 충분하다. 만약에 컴퓨터의 숫자를 생성하길 원하거나 결과를 보여주기를 원한다면, SciPy를 시도하세요.
SciPy website 에서 좀 더 자세하게 Download 와 설치에 대한 문서를 읽어보도록 하자.

PEP 8: Python Style Guide

per se 소프트웨어 도구를 사용하지 않는다면, PEP 8은 Python에 관련된 정말 중요한 Resource이다.
PEP 8은 메인 Python 배포의 표준 Library 집합에서 사용되는 Python Code의 Coding Conventions의 정의를 다룬 문서이다. 이 문서의 중요한 목적은 코드의 같은 물리적 레이어와 변수의 Naming 패턴, Class와 Function의 이름을 가진 Python Code를 보장하는 것이다. 이것을 전부 이해하고 따르길 바란다. 많은 시간을 줄여줄 것이다.

The Mighty Python Standard Library

Python의 기본 Library는 매우 다양하고, 광범위한 분야를 제공하고 있다. 이 Library는 C로 짜여진 File I/O 같이 System에 접근할 수 있는 기능을 가진 Built-in Modules를 포함한다. 또한, 매일 개발할 때 발생 되는 많은 문제들을 해결하는 표준적인 해결법을 Python으로 제작된 Modules이다. 이 Modules의 몇은 Platform 고유의 APIs 를 이용하여 Platform에 맞춰 Python 프로그램이 좀 더 잘 돌 수 있도록 명시적으로 설계 되어있다. 
Official documentation for the Standard Library 이 곳에서 다운 받도록 하자.

더 볼 거리

David Goodger가 쓴 Code Like a Pythonista: Idiomatic Python 에서는 많은 핵심적인 Python 문법과 고급 테크닉, 그리고 당장에라도 사용할 수 있는 좋은 도구에 대해서 다루고 있다.
Doug Hellmann의 훌륭한 시리즈인 Python Module of the Week가 있다. 이 시리즈는 Python의 기본 Library에 있는 Module들을 활용하는 예제들이 있다.

마치며

여기서 다루고 있는것은 단지 수박 겉 핥기이다. 유용한 도구, Library 그리고 상상할 수 없는 일도 할 수 있는, 그리고 혼자서는 다 완성하지 못할 Python을 위한 소프트웨어들이 있다. 그러한 것은 스스로 찾아봐야 할 것이다.
Python은 대단히 좋은 커뮤니티가 있으며, 이 곳에 속한 사람들은 희생적이며 새롭게 시작하는 사람들에게 도움을 주는 태도를 가지고 있다. 그러므로, 선호하는 Open source project의 IRC 채널에 항상연결을 하라. 그리고 Mailing List에 가입을 하고, Python 뿐만 아니라 다른 것들로 이뤄진 작고 큰 system을 향상시키는 경험에 대해서 얘기를 하라. 시간이 지나면 당신의 경험과 지식이 스스로를 발전 시켜줄 것이다.
난 Zen Of Python에 있을 것이다. 생각하고, 생각하라. 그리고 깨어나라! 즐거운 파이선 개발.

>>> import this

The Zen of Python, by Tim Peters



Beautiful is better than ugly.

Explicit is better than implicit.

Simple is better than complex.

Complex is better than complicated.

Flat is better than nested.

Sparse is better than dense.

Readability counts.

Special cases aren't special enough to break the rules.

Although practicality beats purity.

Errors should never pass silently.

Unless explicitly silenced.

In the face of ambiguity, refuse the temptation to guess.

There should be one-- and preferably only one --obvious way to do it.

Although that way may not be obvious at first unless you're Dutch.

Now is better than never.

Although never is often better than *right* now.

If the implementation is hard to explain, it's a bad idea.

If the implementation is easy to explain, it may be a good idea.

Namespaces are one honking great idea -- let's do more of those!
This entry was tagged pythonprogrammingtoolstutorial

Discussions/Feedback.

If you wish to, you can discuss/mock/upvote/downvote at Hacker News.
I do not accept comments on this blog. Managing the spam is a headache and I am better off without it. However, I do welcome your feedback - good or bad via email at feedback@mirnazim.org. Specifically, I would be grateful for your feedback on errors, omissions, broken links, etc.

Credits.


My gratitude to the the people who provided valuable feedback over the Hacker News discussion and via direct email. A special thanks to Nathaniel Guy who took out time and actually sent me a patch with improvements in grammar, naration and other some other fixes.

1 comment: