파이썬

From Hidden Wiki
Revision as of 08:58, 22 October 2017 by Pie (talk | contribs)
Jump to navigation Jump to search

개요

파이썬(Python)은 프로그래밍 언어의 일종이다. 창시자는 귀도 반 로섬(Guido van Rossum). 네덜란드어 발음으로 '히도 판 로쉼'. 1989년 크리스마스 주에 연구실은 닫혀있고 심심해서 만들었다. 귀도가 즐겨 보던 영국의 6인조 개그 그룹 몬티 파이선(Monty Python)에서 이름을 땄다.


파이썬객체 지향 프로그래밍(object-oriented programming) 언어에 속한다. 객체 지향 프로그래밍 전에 절차적 프로그래밍(procedural programming) 언어가 먼저 개발되었다. 절차적 프로그래밍 언어에서 구조적 프로그래밍이 나왔다. 현재는 절차적 프로그래밍 언어에도 객체 지향 프로그래밍 개념이 포함되어있다. 루비(Ruby)라고 파이썬과 유사한 프로그래밍 언어가 일본에서 만들어졌다. 루비도 세계적으로 꽤 많이 쓰인다.


자바(Java), C 언어(C), C플플(C++), C샾(C#), 파이썬(Python)이 전세계에서 가장 많이 쓰이는 다섯 개의 프로그래밍 언어이다. 애플(Apple)에서 많이 쓰이는 오브젝티브-C(Objective-C)도 C 언어 파생 언어 중 하나이다. C샾은 마이크로소프트(Microsoft)에서 만들었다. 거의 애플용으로만 쓰이는 오프젝티브-C처럼 C#도 거의 MS용으로만 쓰인다. 자바, C언어, C++, 파이썬은 리눅스,맥OS, 아이OS(iOS), 윈도우즈운영 체제를 가리지 않고 다양한 개발에 쓰인다.


파이썬은 서버쪽 언어(server-side language)로도 쓸 수 있어서 웹 프로그래밍에서도 많이 쓰인다. 그 외에 피에이치피(PHP)가 유명하다. 클라이언트쪽 언어(client-side language)로 많이 쓰이는 건 그 유명한 자바스크맆트(JavaScript)이다. 자바스크맆트를 서버쪽 언어로 쓸 수도 있는데 그 때 쓰는 게 노드.js(Node.js)이다. 프로그래밍 언어스크맆트 언어인 경우 서버쪽 스크맆트(server-side script)와 클라이언트쪽 스크맆트(client-side script)라고도 부른다.

특징

높은 생산성

http://xkcd.com/353/ 파이썬의 높은 생산성에 대한 만화 ~~뭐야 이거 2.x 버전이잖아~~

인터프리터 언어이면서 우수한 자료형과 다양한 모듈 등을 제공해 개발기간이 매우 단축되는 것이 특징. 'C 언어로 2년동안 완성하지 못한 프로젝트를 파이썬으로 한달만에 해냈다'는 극적인 경험담이 있을 정도다. C언어와의 접착성도 좋기 때문에, 일단 Python으로 빨리 구현하고, 남은 시간에 속도에 병목이 되는 부분을 C로 전환하는 전략을 내세우고 있다. 버전이 올라가면서 Python 자체도 그리 느리지 않게 되었다. ~~맛들이면 다른 언어로 전환하기 힘든 부작용이 생긴다 카더라.~~

참고로 저 xkcd 만화는 파이썬에서 import antigravity라고 하면 나오는 이스터 에그이다.(...) http://www.youtube.com/watch?v=_V0V6Rk6Fp4

디자인 철학

(Perl)의 프로그래밍 모토(motto)는 "프로그래밍하는 데는 한 가지 이상의 방법이 있다.(There's more than one way to do it이고 TMTOWTDI 또는 TIMTOWTDI로 줄여서 얘기함. Tim Toady라고 발음함.)"이다. 반면, 파이썬(Python)의 20번째 PEP(Python enhancement proposal, 파이썬 향상 제안)는 파이썬의 (zen, 선종 불교(교지)을 얘기함.)인 The Zen of Python인데, 파이썬의 젠 중 하나는 "문제를 해결하는 데는 명백한 하나의 방법(그리고 선호되는 오로지 하나의 방법)만 있어야 한다.(There should be one-- and preferably only one --obvious way to do it.)이다. 이 젠을 펄의 모토와 대비시켜서 간략화한 것이 "문제를 해결하는 데는 오직 하나의 방법만 있다.(There's only one way to do it, 줄여서 TOOWTDI)"이다. PEP 20의 저자는 Tim Peters이다.


PEP 8은 Style Guide for Python Code이며 저자는 Guido van Rossum, Barry Warsaw, Nick Coghlan이다. PEP 8에서는 들여쓰기(indentation)에 (tab)을 쓰지말고, 스페이스 바(space bar)를 쓰라고 하며, "스페이스 바"로 4칸을 띄우라고 규정한다.


Perl의 '하나 이상의 해결법이 존재한다' 와는 정반대로 '가장 아름다운 하나의 답이 존재한다'라는 명제를 모토로 하고 있다. 이 모토 하에 다음과 같은 철학(zen)을 지니게 되었다.

* 아름다운 것이 추한 것보다 낫다.(Beautiful is better than ugly)
* 명쾌한 것이 암시적인 것보다 낫다. (Explicit is better than implicit) 
* 간결한 것이 복잡한 것보다 낫다. (Simple is better than complex)

따라서 다른 언어들의 코딩 스타일은 각자의 취향에 맞게 발산진화 하는 반면[* 실제로 c계열의 언어에서 중괄호의 위치에 대한 논쟁은 거의 종교적 논쟁에 가깝다. 현재 한국에서 가장 많이 쓰이는 방식은 C언어의 창시자 Kernighan과 Ritchie의 K&R 스타일이다. 그러나 Eric Allman의 방식을 고수하는 사람들도 제법 많다. 이외에도 중괄호 위치를 정하는 다른 방법들이 있으며 자세한 내용은 에서 확인가능, 파이썬은 위의 철학들을 만족시키는 하나의 스타일로 수렴진화하는 성향이 있다. 이런 성향은 다른언어에는 없는 파이썬스러움(pythonic)이라는 독특한 개념을 낳게 되었는데, 복잡하지 않으면서 의미가 명확하고, 심플한, 파이썬의 철학을 따르는 것들을 지칭하는 개념이다.

이런 철학 때문에 문법이 굉장히 엄격한 편이다. 예를 들자면, 다른 언어에서는 해도 되고 안 해도 되는 들여쓰기가 이 언어에서는 의무로 들여쓰기 자체로 하나의 코드 블럭이 된다. 코드 블럭을 명시적으로 표시하지 않아도 돼서 비쥬얼 적으로는 굉장히 깔끔한 반면[* 특히 코드를 종이에 출력해보면 중괄호 있고 없고의 가독성 차이가 의외로 크다], 자유도를 제약한다는 평도 있다.

def factorial(x):
    if x == 0:
        return 1
    else:
        return x * factorial(x - 1)

파이썬 프로그래밍 기초

리눅스라면 기본적으로 파이썬 2.x와 3.x가 기본으로 깔려있다. 윈도우즈맥 OS 사용자의 경우 https://www.python.org/downloads/ 에서 다운로드 받아 설치한다. 안드로이드의 경우 플레이 스토어(Play Store)에서 SoloLearn에서 만든 Learn Python같은 걸 설치하여 파이썬 프로그래밍을 배워도 좋다. 지금은 여러 잡다한 프로그래밍 학습 앱이 "SoloLearn: Learn to Code for Free" 하나로 합쳐져서 Learn Python 대신에 새로 나온 앱을 깔아야 한다.


칼리 리눅스 기준으로 설명하겠다. 우선 터미널을 띄운다. 그리고 아래와 같이 입력하면 파이썬 2.7.12가 실행된다.

python

그리고 뜬 >>>에 소스 코드를 쓰면 된다.

print("hello world")

라고 치면

hello world

라고 뜬다. print는 모니터 화면에 출력하라는 의미이다. 이제 exit()를 입력하거나 컨트롤 키(Ctrl)와 d 키를 동시에 눌러 빠져나온다.


이제 터미널에

python3

를 입력하여 파이썬 3.5.2를 실행시켜보자. 거기에

print("hello world")

를 입력하면 역시

hello world

라고 뜬다.


요즘에는 파이썬 2.x 버전은 잘 안 쓰니, 파이썬 3.x 버전을 쓰도록 하자. 아래의 모든 예문은 파이썬 3.x를 기준으로 작성되어졌다.


>>> 뒤에 2+4라고 입력하면 6이라고 뜨고, 3+2-7이라고 입력하면 -2이라고 뜬다. 3*7을 하면 21이 뜨고, 3/4를 해보면 0.75가 뜨고, 3/7을 하면 0.42857142857142855가 뜬다. *는 곱하기고, /는 나누기다. 역시 exit()를 입력하여 종료시킨다.


그 후 지에디트(gedit), 리프패드(Leafpad), 메모장(Notepad) 등 아무 거나 열어서 다음을 입력해보자. 들여쓰기(indentation)는 (Tab) 키, 스페이스 바(space bar) 두 번 또는 네 번으로 한다. 운영 체제편집기마다 탭 키의 간격이 다르기 때문에 동일한 스페이스 바를 사용해서 들여쓰기를 하는 게 낫다. 또한 파이썬 코딩 스타일 가이드(PEP 8)에서는 공백 4칸으로 규정하고 있으므로 스페이스 바 네 번으로 들여쓰기를 해주자.

i=1
while i<=7:
    print(i)
    i=i+1
print("Finished!")

그리고 이름은 대충 test.py로 하고, 저장한다. i=1은 i의 초기 값이 1이라는 의미이다. while i<=7:은 i가 7이 될 때까지 반복하라는 의미이다. <=는 작거나 같다는 의미이고, >=는 크거나 같다는 의미이다. i=i+1은 원래 있던 i 값에 1을 더하여 i 값을 1 늘려주라는 의미이다.

그리고 터미널에서 test.py가 있는 디렉터리로 이동 후

python3 test.py

라고 치면 아래와 같은 결과가 뜬다.

1
2
3
4
5
6
7
Finished!


이제 아래와 같이 지에디트에 적고 test2.py라는 이름으로 저장해보자.

i=0
while True:
    i=i+1
    if i==3:
        print("Skipping 3")
        continue
    if i==7:
        print("Breaking")
        break
    print(i)
print("Finished")

while True:는 while문을 계속 반복하라는 의미이다. True 대신에 1을 써도 된다. 반대로 while False:나 while 0:을 쓰면 while문이 바로 종료되면서 Fihished만 출력되고 끝난다. 하지만 되도록이면 1이나 0 대신에 True와 False를 쓰는 게 좋다. if i==3:은 만약 i가 3이라면 if문을 실행하라는 의미이다. ==는 같다는 의미이다. 프로그래밍에서 =는 같다는 의미가 아니라, 변수를 선언하는 의미이다. 즉, i=0은 i라는 변수에 0을 넣으라는 의미고, i=i+3은 이전의 i 값에 3을 더한 값을 새로운 i 값으로 한다는 의미이다. continue는 if문을 계속 하라는 의미이고, break는 if문을 끝내라는 의미이다.

그리고 터미널에서

python3 test2.py

를 입력하면

1
2
Skipping 3
4
5
6
Breaking
Finished

라고 뜰 것이다.

주석

파이썬에서 사람만 알아볼 수 있도록 작성하는 부분을 주석(comment)이라고 합니다. 즉, 주석은 파이썬 인터프리터가 처리하지 않으므로 프로그램의 실행에는 영향을 주지 않습니다. 보통 주석은 코드에 대한 자세한 설명을 작성하거나, 특정 코드를 임시로 사용하지 않도록 만들 때 사용합니다.


주석은 한 줄 주석과 범위 주석 두 가지가 있는데 다음은 한 줄 주석으로 코드에 대한 설명을 작성한 모습입니다.

# Hello, world! 출력


코드 맨 앞에 #을 사용하면 해당 줄은 모두 주석이 됩니다. 따라서 다음 print 함수는 동작하지 않습니다.

#print('Hello, world!')


코드를 뒤에 #으로 주석을 작성할 수도 있습니다. 이때 앞에 있는 코드만 정상적으로 동작하며 # 뒤에 있는 코드는 동작하지 않습니다.

a = 1 + 2 # 더하기
print('Hello, world!') #printf('1234567890')


파이썬에서 여러 줄을 주석 처리할 때는 ' 또는 " 3개를 붙여서 쓰세요.

'''
i am comment!
multiline!!!!
'''


아래는 주석 사용 예시입니다.

#!/usr/bin/python
# -*- coding: cp949 -*-
# 이렇게 앞에 샤프(#) 기호가 있으면 주석문입니다.
print "안녕하세요"    # 각 행 뒤에 주석 기호를 붙일 수도 있음
print 1 + 1           # 출력 결과: 2
"""
여기는 도큐멘트 스트링인데, 블록 코멘트로 사용할 수 있고
이렇게, 큰따옴표 3개 사이에 아무 문장이나 쓸 수 있습니다.
다만, 각 들여쓰기 레벨에 맞아야 합니다.
"""
def example2(x, y):
    z = x + y
    """
    블록 코멘트
    블록 코멘트
    블록 코멘트
    """
    return z
print example2(2, 3)


그리고 소스에서

#!/usr/bin/python
# -*- coding: cp949 -*-

이런 부분은 주석이 아니고 특수한 의미를 가지고 있는 행입니다.

터미널에서 실행하는 소스 코드

삼각형 그리기

print('\n'.join(('*'*(2*y-1) for y in range(1,20))))

1부터 N까지 출력

for x in range(int(input("n을 입력해 주십시오: "))):
    print(x+1)

또는

_ = list(print(x+1) for x in range(int(input("n을 입력해 주십시오: "))))

구구단

_ = list(eval(r"print(x, '*', y, '=', x*y, end = ('\n' if y == 9 else ' '))") for x in range(2,10) for y in range(1,10))

99병의 맥주

99병의 맥주(99 Bottles of Beer)는 미국과 캐나다 등에서 자주 불리는 권주가(勸酒歌)이다. 벽장에 있는 99개의 맥주병을 하나씩 꺼내면서 수가 줄어드는 걸 노래하고 있다.

start = 99
def bottles(i, leading):
    if i < 0:
        i = start
    _n = "N" if leading else "n"
    _s = "s" if i != 1 else ""
    _i = str(i) if i != 0 else _n + "o more"
    return _i + " bottle" + _s
take_or_buy = lambda i: "Go to the store and buy some more" if i == 0 else "Take one down and pass it around"
for i in range(start, -1, -1):
    print(bottles(i, True) + " of beer on the wall, " + bottles(i, False) + " of beer.")
    print(take_or_buy(i) + ", " + bottles(i - 1, False) + " of beer on the wall.")
    print("")

GUI 지원되는 소스 코드

파이썬에서는 아래와 같이

import tkinter as tk

from tkinter import *

같은 Tkinter를 불러오라는, 단 한 줄의 소스 코드로 간단하게 그래픽 유저 인터페이스(GUI)를 구현할 수 있다.

리눅스 민트에는 python3-tk 패키지가 설치되어있지 않으므로 터미널에서

sudo apt-get install python3-tk

하여 관련 패키지들을 설치해준다.


아무 것도 없는 창

from tkinter import *

root=Tk()
root.mainloop()

위에서 생성된 최상위창은 tkinter 애플리케이션에서 가장 높은 수준의 GUI구성요소이며, 최상위 창의 이름은 'root'로 하는것이 관례적이다.

packing 하기

아래 예제에서 tkinter 프로그래밍의 세가지 주요 개념이 나온다.

>GUI객체를 만들어서 그의 부모객체와 연관시키기

>packing

>그릇(containers)와 창부품(widgets)

from tkinter import *

root = Tk()

F = Frame(root) #root와 F의 논리적인 부모자식관계 정의
F.pack() #F를 packing하여 시각적으로 보여지도록 함

root.mainloop()

tkinter의 최소, 최대 크기를 지정하지 않으면, 창부품의 여부에 따라 창크기가 자동으로 조절된다.

5행 : root와 F는 논리적인 부모자식관계가 정의된다.

6행 : 논리적인 부모관계에서 시각적인 관계로 설정한다.

즉, 애플리케이션에 보여지도록 설정한다.

창 부품(위젯) 꾸리기

창 가운데 녹색 버튼 띄우기.

아래 예제에서는 창부품을 만들어서 그것을 F라는 프레임에 집어넣는다.

이번 예제에서 사용될 창부품은 Button이 사용됐으며, 버튼창부품에는 크기, 전경색, 배경색, 표시텍스트, 테두리모양 등의 속성이 있는데,

이는 창부품의 지역이름공간에 dict형으로 저장되어 있다. 버튼창부품외에 다른 창부품역시 속성은 창부품지역이름공간에 dict형으로 저장되어진다.

아래 예제는 button1 창부품에 2개(표시텍스트, 배경색)의 속성만 설정하였다.

이전에 설명한것과 마찬가지로 Button을 생성한 후엔 반드시 packing을 해줘야만 어플리케이션에서 보여질수 있다.

from tkinter import *

root = Tk()

F = Frame(root)
F.pack() #packing

button1=Button(F)
button1['text']="로리 망꼬 다이스키!"
button1['background']='green'
button1.pack() #packing

root.mainloop()

button1버튼이 생성되자 F의 공간이 자동으로 늘어난것을 알수 있다.

위 예제의 부모자식 구조는 root - F - button1 이라 할수 있겠다.

즉, root의 자식은 F이며, F의 자식은 button1이 되는것이다.

클래스 구조

왜 애플리케이션을 클래스로 구성하는가?

프로그램에 클래스 구조를 사용하는 이유는 프로그램을 제어하기가 더 쉽기 때문이다.

큰 프로그램일수록 클래스로 구축되었을때가 그렇지 않은경우에 비해 이해하기가 쉽다.

아래 예제는 위의 예제와 기능적으론 전혀 차이가 없지만, 코드상으론 클래스형태로 구현된것이다.

from tkinter import *

class MyApp:
    def __init__(self,Parent):
        self.F=Frame(Parent)
        self.F.pack()

        self.button1=Button(self.F)
        self.button1["text"]="로리 망꼬 다이스키!"
        self.button1["background"]="green"
        self.button1.pack()
root = Tk()
myapp=MyApp(root)
root.mainloop()

중앙에 닫기 버튼이 있는 창

import tkinter as tk
class Application(tk.Frame):
    def __init__(self, master=None):
        tk.Frame.__init__(self, master)
        self.grid()  
        self.createWidgets()
    def createWidgets(self):
        self.quitButton = tk.Button(self, text='보지질싸', command=self.quit)
        self.quitButton.grid()
app = Application()
app.master.title('Sample application')
app.mainloop()

속성 설정하기

from tkinter import *

class MyApp:
    def __init__(self,Parent):
        self.F=Frame(Parent)
        self.F.pack()

        self.button1=Button(self.F)
        self.button1["text"]="로린이 따먹자!"
        self.button1["background"]="green"
        self.button1.pack()

        self.button2=Button(self.F)
        self.button2.configure(text="오토코노코도 따먹자!")
        self.button2.configure(background="tan")
        self.button2.pack()

        self.button3=Button(self.F,text="그러다 너도 흑형한테 따먹힘.",background="red")
        self.button3.pack()

root = Tk()
myapp=MyApp(root)
root.mainloop()

위의 예제를 버튼을 3개를 만들었다.

버튼의 속성을 설정하는 방법이 약간씩 다른데,

button1버튼은 dict로 된 이름공간을 이용했고,

button2버튼은 configure메서드를 이용했고,

button3버튼은 생성함과 동시에 속성을 설정하였다.


또 한가지 주목할점은 버튼을 추가한 순서대로 차곡차곡 쌓이며 보여지는것을 알수 있다.

정렬

packing은 구성요소의 시각적 관계를 제어하는 방법이다.

pack 메서드는 side옵션을 사용하여 버튼의 위치를 정렬을 조절할수 있다.

from tkinter import *

class MyApp:
    def __init__(self,Parent):
        self.F=Frame(Parent)
        self.F.pack()

        self.button1=Button(self.F)
        self.button1["text"]="유두"
        self.button1["background"]="green"
        self.button1.pack(side=LEFT)

        self.button2=Button(self.F)
        self.button2.configure(text="요도")
        self.button2.configure(background="tan")
        self.button2.pack(side=LEFT)

        self.button3=Button(self.F,text="보지",background="red")
        self.button3.pack(side=LEFT)

        self.button4=Button(self.F,text="항문",background="cyan")
        self.button4.pack(side=LEFT)

root = Tk()
myapp=MyApp(root)
root.mainloop()

위에서 사용된 LEFT(RIGHT,TOP,BOTTOM)는 tkinter내에 정의되어 있다.

즉, tkinter.LEFT라는 뜻이다.

"from tkinter import *" 와 같은 형식으로 tkinter모듈을 임포트 하였으므로,

tkinkter을 붙이지 않고 위처럼 바로 사용할수 있는것이다.

수직적동선에는 TOP과 BOTTOM이 있으며

수평적동선에는 LEFT와 RIGHT가 있다.

버튼이 출력되는 순서는 packing한 순서이며,

button1보다 button2를 먼저 packing했다면 button2가 먼저 보여질것이다.


그러나 한 그릇안에서 이런식으로 동선을 섞어서 사용하는 것은 좋은 생각이 아니다.

동선을 섞어 쓰게 되면, 최종적으로 어떻게 보일지 예측하기가 힘들고,

창크기를 조절할때 GUI가 일그러질수도 있기 때문이다.

그래서 좋은 디자인 습관은 같은 그릇안에서 절대로 동선을 섞어 쓰지 않는 것이다.

복잡한 GUI를 다루는 방법으로 여러 동선을 사용하고 싶을땐, 그릇안에 그릇을 내포시키는 것이다.

사건 묶기

사건묶기(binding)이란 다음과 같은 객체들 사이의 관계 또는 연결을 정의하는 과정이다.

>창부품

ex) Button

>사건

ex) <Button-1>(마우스왼쪽클릭)

>사건처리자

ex) Button1Click메서드

이제 버튼에게 일을 시킬 시간이다.

아래 예제는 버튼 창부품을 생성하고, 버튼창부품에 사건(<Button-1>)과 사건처리자(button1Click)를 묶어줌으로써

버튼을 클릭하였을때 지정한 사건처리자가 동작하게끔 한것이다.

※ "<Button-1>" 은 마우스왼쪽 클릭을 의미한다.

from tkinter import *

class MyApp:
    def __init__(self,Parent):
        self.myParent=Parent #부모, 즉 루트를 기억
        self.F=Frame(Parent)
        self.F.pack()

        self.button1=Button(self.F,text="하지원 팬티색",background="green")
        self.button1.pack(side=LEFT)
        self.button1.bind("<Button-1>",self.button1Click)

        self.button2=Button(self.F,text="자궁색",background="red")
        self.button2.pack(side=RIGHT)
        self.button2.bind("<Button-1>",self.button2Click)

    def button1Click(self,event):
        if self.button1["background"]=="green":
            self.button1["background"]="yellow"
        else:
            self.button1["background"]="green"

    def button2Click(self,event):
        self.myParent.destroy()

root = Tk()
myapp=MyApp(root)
root.mainloop()

"하지원 팬티색" 버튼을 클릭하면 팬티의 색이 바뀌고, "자궁색" 버튼을 클릭하면 destroy() 메서드를 호출하여 창이 닫히게된다.

※ 버튼이라는 단어는 완전히 다른 두가지를 지칭하기 위해 사용될수 있다.

첫번째는 버튼창부품이고(화면상에 보이는 버튼),

두번째는 마우스의 버튼이다(마우스에서 손가락으로 누르는 버튼)

따라서 이런 혼란을 피하기 위해 버튼이라고 하지 않고, "버튼창부품" 과 "마우스버튼"이라고 구분하여 설명하도록 하겠다.


11행 : button1버튼창부품에서 일어날 사건을 bind메서드를 이용하여 묶어주었다.

<Button-1>은 "왼쪽마우스클릭"사건이다. 즉, 왼쪽마우스를 클릭하면 사건이 발생하는것이다.

여기에 Button1Click라는 버튼창부품색을 변경해주는 함수를 묶어줌으로써

'하지원 팬티색' 버튼창부품을 클릭하면 '하지원 팬티색' 버튼창부품의 색이 변경된다.


23행 : '자궁색' 버튼창부품을 왼쪽마우스로 클릭하면 button2Click함수가 동작하고,

button2Click함수는 myapp의 부모창인 root창의 destroy()메서드를 호출하였다.

이렇게 하면 root아래의 모든 자식과 자손이 연달아 종료된다.

즉, GUI의 모든 부분이 소멸된다.

이런식으로 동작하려면 myapp은 자신의 자손이 누구인지 알아야 한다. 그래서 5행에서 myapp이 그의 부모를 기억하도록 한것이다.

초점

위의 예제에서는 마우스로 클릭하면 버튼에게 일을 시킬수 있었다.

다음 프로그램에서는 마우스뿐만 아니라 키보드에도 반응시키는 방법을 다루도록 하겠다.

먼저, "입력초점(input focus)" 또는 그냥 단순하게 "초점(focus)"이라는 개념을 알필요가 있다.

"초점(focus)"은 GUI상의 창부품들에게 키보드 사건을 볼수 있도록 해준다.

즉, 한 순간에 오직 한 창부품만 초점을 가진다. 그리고 초점을 가진 창부품만 키보드사건을 보고 반응할수 있다.

창부품에 초점을 설정하는 일은 그 초점을 창부품에 부여하는것이다.


예를 들어 다음 프로그램에서는 OK와 Cancel이라는 2개의 버튼부품창이 있다.

Tab키를 누르면 OK버튼과 Cancel버튼을 번갈아가며 초점이 보여지게 된다.

따라서 button1에 초점을 맞추고 <Return>키를 누르게 되면 사건처리자(button1Click)가 동작하게 된다.

※ <Return>은 Enter키를 누르는것을 의미한다.

from tkinter import *

class MyApp:
    def __init__(self,parent):
        self.myparent=Frame(parent)
        self.F=Frame(parent)
        self.F.pack()

        self.button1=Button(self.F)
        self.button1.configure(text="하지원 팬티색",background="green")
        self.button1.pack(side=LEFT)
        self.button1.bind("<Button-1>",self.button1Click)
        self.button1.bind("<Return>",self.button1Click)

        self.button2=Button(self.F)
        self.button2.configure(text="자궁색",background="red")
        self.button2.pack(side=RIGHT)
        self.button2.bind("<Button-1>",self.button2Click)
        self.button2.bind("<Return>",self.button2Click)

    def button1Click(self,event):
        report_event(event)
        if self.button1["background"]=="green":
           self.button1["background"]="yellow"
        else:
           self.button1["background"]="green"

    def button2Click(self,event):
        report_event(event)
        self.myparent.destroy()

def report_event(event):
    event_name={"2":"KeyPress","4":"ButtonPress"}
    print("시간:",str(event.time))
    print("이벤트 종류 = "+str(event.type))
    print(event_name[str(event.type)])
    print("이벤트 위젯 아이디 =",event.widget)
    print("이벤트 키 심벌 =",event.keysym)
    print()

root=Tk()
MyApp(root)
root.mainloop()

계산기

https://www.daniweb.com/programming/software-development/code/467452/updated-tiny-tkinter-calculator-python

''' tk_calculator_tiny2.py
A updated tiny calculator using the Tkinter GUI toolkit
you can type in functions contained in module math
for instance type in  tan(pi/180)  then click  =
tested with Python27 and Python33  by  vegaseat  13nov2013
'''
# avoid integer division by Python2
from __future__ import division
from math import *
from functools import partial
import tkinter as tk
class MyApp(tk.Tk):
    def __init__(self):
        # the root will be self
        tk.Tk.__init__(self)
        self.title("Tiny TK Calculator")
        # use width x height + x_offset + y_offset (no spaces!)
        #self.geometry("300x150+150+50")
        # or set x, y position only
        self.geometry("+150+50")
        self.memory = 0
        self.create_widgets()
    def create_widgets(self):
        # this also shows the calculator's button layout
        btn_list = [
        '7',  '8',  '9',  '*',  'C',
        '4',  '5',  '6',  '/',  'M->',
        '1',  '2',  '3',  '-',  '->M',
        '0',  '.',  '=',  '+',  'neg' ]
        rel = 'ridge'
        # create all buttons with a loop
        r = 1
        c = 0
        for b in btn_list:
            # partial takes care of function and argument
            cmd = partial(self.calculate, b)
            tk.Button(self, text=b, width=5, relief=rel,
                command=cmd).grid(row=r, column=c)
            c += 1
            if c > 4:
                c = 0
                r += 1
        # use an Entry widget for an editable display
        self.entry = tk.Entry(self, width=33, bg="yellow")
        self.entry.grid(row=0, column=0, columnspan=5)
    def calculate(self, key):
        if key == '=':
            # guard against the bad guys abusing eval()
            if '_' in self.entry.get():
                self.entry.insert(tk.END, " not accepted!")
            # here comes the calculation part
            try:
                result = eval(self.entry.get())
                self.entry.insert(tk.END, " = " + str(result))
            except:
                self.entry.insert(tk.END, "--> Error!")
        elif key == 'C':
            self.entry.delete(0, tk.END)  # clear entry
        elif key == '->M':
            self.memory = self.entry.get()
            # extract the result
            if '=' in self.memory:
                ix = self.memory.find('=')
                self.memory = self.memory[ix+2:]
            self.title('M=' + self.memory)
        elif key == 'M->':
            if self.memory:
               self.entry.insert(tk.END, self.memory)
        elif key == 'neg':
            if '=' in self.entry.get():
                self.entry.delete(0, tk.END)
            try:
                if self.entry.get()[0] == '-':
                    self.entry.delete(0)
                else:
                    self.entry.insert(0, '-')
            except IndexError:
                pass
        else:
            # previous calculation has been done, clear entry
            if '=' in self.entry.get():
                self.entry.delete(0, tk.END)
            self.entry.insert(tk.END, key)
app = MyApp()
app.mainloop()

언어 구현

보통 말하는 Python은 C언어로 구현되었으며, 다른 구현체와 구분하여 언급할 때에는 CPython이라고 표기한다. CLR 바이트코드로 구현된, 즉 닷넷프레임워크 위에서 동작하는 IronPython, CPython에서 C 스택을 없앤 Stackless Python, JVM바이트코드로 구현되어 JVM위에서 돌아가는 Jython[* 이전 버전 문서에는 C#으로 구현된 Ironpython, Java로 구현된 Jython이라고 되어있었으나 이는 명백한 오류다. Jython이 JVM바이트코드가 아니라 java로 구현된거라면 안드로이드 dalvik vm에서는 왜 안돌아간다고 생각하는가? ] , 파이썬 자체로 구현된 PyPy 등이 있으며 이 가운데 오리지날은 CPython이다. 또한, 현재[* 2014년 6월] Dropbox에서 Pyston이란 LLVMJIT 기반 파이썬을 개발 중이다.DROPBOX TECH BLOG

한편 중국에서는 Chinese Python이라는, 중국어 문법으로 한자를 쳐서 돌아가는 언어를 독자 개발했다. 오오 중국 오오.

Python 3.x

사용자가 늘다 보니 여러 단점들이 지적되었는데, 과감하게 하위 호환성을 포기하고 Python 3000 이라는 코드명으로 개발하기 시작하여 발표된 버젼이다. 내부적으로는 많이 변했다고 하는데 겉보기에는 별로 변한 것 같지 않다는 것이 함정. 그러나 소소한 부분에서 문법과 기본 라이브러리에 차이가 있어 호환이 되지 않는다. 2to3이라는 python2를 python3로 바꿔주는 컨버터가 있어서 전부 갈아 엎어야 하는 수고는 덜 수 있다.

Python을 실제로 사용하게 되면, 구현에 필요한 기능을 지원하는 여러 패키지를 받아서 설치해 사용하게 된다. Python 2.x vs Python 3.x 에서 선택은 주로 "내가 사용하기 원하는 패키지가 동작하는 환경"에 따라서 선택하게 된다.

파이썬 3.x부터는 유니코드 지원이 더 강화되어 변수나 함수 이름을 한글로 정할 수도 있게 되었다. [* 사실 C++, 자바, 액션스크립트 등 대부분의 현대 프로그래밍 언어들도 한글을 지원하므로 파이썬만의 특징은 아니다. 문제는 IDE가 제대로 받쳐주지 못한 경우가 많다. 적어도 자바와 액션스크립트는 완벽히 지원.] 그러니까... || 이름 = "어쩌고" 나이 = 17 보여줘 = print

보여줘('{} {}'.format(이름, 나이)) || 이런 식으로.

PyPy

본격 Python으로 직접 구현되는 Python. 언뜻 보면 CPython보다 느릴 것 같지만 실제로는 더 빠른 실행결과도 보여주는 흠좀무한 녀석이다. 어떠한 외계의 기술이 적용되어서 이것이 가능한지는 PyPy 문서를 참조하라.


2007년에 처음 발표된 Python의 언어 구현 하나로, C로 짜인 기존의 CPython과 달리 Python으로 Python을 만드는 프로젝트이다.[* 부트스트래핑이라고 한다.] 여기까지 얘기하면 뭔가 이상한 짓 하는 프로젝트 내지 실험적인 프로젝트처럼 느껴지겠지만, 이 프로젝트의 진짜 놀라운 점은 기존 CPython보다 전혀 느리지 않을 뿐더러, 오히려 성능면에서 CPython을 능가하고 있다는 거다. 나아가 [링크]에서 보이는 대로, 계속해서 빨라지고 있다! [구현인 CPython과의 속도비교. PyPy를 개발하면서 지속적으로 업데이트 하고 있다.]


이 구현은 애초에 그저 장난질 하려고 시작한 프로젝트가 아니다. [[1]]라고 하는, 기존 파이썬 위에다가 Just-In-Time 컴파일을 구현해서 실행성능을 높히는 프로젝트가 있었는데, 이걸 개발하던 [Rigo]라는 사람이 아예 JIT 컴파일을 하는 파이썬을 처음부터 다시 구현하기로 생각했다. 그래서 2003년부터 PyPy 개발을 시작하여 유럽연합의 연구자금 지원을 받아가며 지금도 개발하고 있다.

2017년 8월 기준으로, PyPy3는 윈도우 바이너리가 없으므로 리눅스 바이너리를 실행시켜야 한다. 윈도우 10이라면 1주년 업데이트에 포함된 리눅스 배시 기능을 쓰거나, 윈도우로 리눅스 어플리케이션을 돌리는 프로그램을 이용할 수도 있다.

어떻게 구현하나

기계어컴파일하지 않고 기껏해야 인터프리팅 성능을 빠르게 하기 위해 스크립트만을 쓰는 Python을 가지고 파이썬으로 돌리는 파이썬을 어떻게 만들었을까. PyPy의 접근법은 이렇다.

1. 먼저 RPython이라고 하는, 파이썬 문법을 엄격하게 만들어 컴파일이 되게 만든 해석기(translate.py)를 Python 코드로 작성한다.[* RPython는 Python의 일부만 구현한 언어(부분 언어)이기 때문에 모든 RPython 코드는 Python 코드이기도 하다. (반대는 성립하지 않는다.)]

2. RPython의 효과적인 컴파일을 위해 다른 언어로 툴체인을 만든다.[* 시뮬레이터에뮬레이터를 제작하는 때에도 이 과정을 반드시 거친다.]

3. Python 구현(런타임)을 RPython 문법으로 작성한다.

4. 3에서 만든 구현을 1 또는 2에서 만든 RPython 해석기로 컴파일한다.

5. 4으로 만든 후보를 이전 또는 다른 구현과 비교(성능 측정), 만족스럽지 않으면 수정한다.(nightly builds)

6. 5에서 만족스러운 결과를 냈다면 출시하고 1 또는 2부터 다시 시작한다.(release)

~~뭔가 속는 느낌이지만~~ 처음 한번만 기존 파이썬의 도움을 받으면 그 다음부터는 스스로 만든 구현으로 저 과정을 자체적으로 계속 반복할 수 있다. 이게 얼핏 보면 '닭이 먼저냐 달걀이 먼저냐' 같은 것으로 착각할 수도 있지만, 이런 식의 접근법은 실제로 프로그래밍 언어를 제작할 때 해당되는 사항이며[* 일례로 유명 c/c++언어 컴파일러인 gcc도 c/c++로 작성되었다. 파이썬이 스크립팅 언어이기 때문에 일견 특이해보이는 것일 뿐, 인터프리터는 어짜피 컴파일된 상태로 돌아가므로 같은 원리다.], 더 좋은 장비의 개발을 위해 기존의 장비를 사용하는 것과 다름이 없다. 이러한 이유로 로고가 우로보로스인 셈. 다만 PyPy는 문자 그대로 진화하고 있다.

사실 이런 식으로 어떤 언어로 자기 자신을 구현하는 것을 부트스트래핑(Bootstrapping) 또는 부팅(Booting)[* 운영체제의 부팅과 같은 어원이다.]이라고 하는데, 사실 이렇게 하는 이유는 처음부터 작업하는 것보다 생산성에서 낫기 때문이다. 처음부터 어셈블리어로 작업하면 이론상 최강의 성능을 발휘할 수는 있으나 그 가능성은 매우 낮고 생산성도 최악이다.(최적화가 그래서 힘들다.) 이 때문에 대부분의 프로그래밍 언어도 초창기에는 어셈블리어나 다른 고급언어의 도움을 받지만, 일정 단계를 넘어서면서 그 한계가 오면 스스로의 컴파일러/인터프리터를 제작하게 된다. Haskell 컴파일러인 GHC와 C/C++ 컴파일러인 GCC가 대표적인 예. 물론 생산성에 중점을 두기 때문에 성능이 눈에 띄게 빨라지는 일은 잘 드러나지 않으며, 단지 우연한 발견 등 여러 이유로 성능이 향상되는 것 뿐이다. PyPy의 경우 Python의 한계를 극복하기 위해 정적인 컴파일이 가능한 RPython을 따로 만들었고 뒤에도 언급할 듯 성능 향상을 위해 7년이라는 긴 세월을 소모했는데, 이것도 어셈블리어로 처음부터 하는 것보다는 짧은 것이다.[* 컴퓨터 하드웨어의 발전도 마찬가지다. 처음 IC나 LSI를 설계할 때는 레이아웃을 손으로 그렸지만, 지금 나오는 칩들은 손으로 하기에는 회로의 규모가 지나치게 크기 때문에 전부 CAD로 개발하고 있다. 사실 이러한 일은 망치를 만들기 위해 망치를 쓰거나 간석기를 만들기 위해 뗀석기를 썼던 것 처럼 인류의 역사를 대표하는 방법론 중 하나이므로 전혀 속는 느낌 가질 거 없다.]

멀티쓰레딩 문제

파이썬은 멀티스레딩을 지원하기 위하여 GIL(Global Interpreter Lock), 즉 전역 인터프리터 락을 도입하여 사용하게 되었다. 따라서, python 스레드 10개를 만들어도 실제 Pthread/윈도우 쓰레드가 10개가 만들어지긴 하는데, GIL때문에 개중 동시에 하나밖에 안돌아가는 기이한 구조를 갖고 있다. [* 물론, 내부적으로 IO작업이 있을시 바로 다른 쓰레드로 문맥 교환을 해주고, 바이트 코트를 100번 실행한 다음에는 인터프리터 차원에서 다른 쓰레드로 교체 해주므로 동시 작업 비슷한 효과가 난다. ] 이것은 구현이 매우 쉬워지고 빠른 개발을 할 수 있다는 장점이 있으나 다중 코어 CPU가 보편화된 2006년 이후에는 다중 코어를 제대로 활용하지 못하는 구조적인 문제 때문에 성능에서 밀린다는 평가를 받게 되었다. 만일 특정 프로그램에 순진하게 CPU 코어를 2개 이상 동원하려고 할 경우, 뮤텍스(MutEx), 즉 한 쓰레드에 여러개의 CPU가 연산을 행하여 내부 정보를 오염시키는 것을 방지하는 역할을 맡는 GIL이 병목 현상을 일으켜 코어 하나를 쓸 때보다 오히려 성능이 크게 저하된다는 것. 구글 내부에서 이미 가루가 되도록 까인 부분이다.

이런 문제점 때문에 파이썬에서 병렬 처리가 필요할때는 다중 쓰레드가 아닌 다중 프로세스로 GIL을 우회하는 방식을 사용한다. 2008년 이후에 Multiprocessing이라는 모듈을 제공하는데 이 모듈은 자식 프로세스를 만드는 방향으로 다중 코어 사용시 성능의 향상을 꾀하고 있다.

단, CPU 부하가 큰 작업을 돌리는 것이 아니면 GIL을 체감하기는 생각보다 쉽지 않다. 다중 쓰레딩으로 CPU의 여러 코어를 최대한 이용하고 싶은 경우에는 GIL가 굉장히 아쉬운 이슈지만, CPU를 별로 쓰지않거나 I/O가 주가 되는 작업은 유의미한 성능 차이가 없다. 게다가 어설프게 코어 몇개 깔짝깔짝 이용해서 계산하는 것보다는 그냥 C언어로 모듈을 짜서 붙이는게 더 빠르다. 즉, python에서 CPU를 많이 먹는 부분은 C 모듈을 짜서 붙이고 필요하다면 multiprocessing 모듈을 이용하여 멀티코어를 활용하는 편. ~~그 이상의 CPU-heavy한 작업은 동적 인터프리팅 언어 쓰지 말고 처음부터 C, C++로 짜는게 맞다~~

자세히 알고싶다면 다음 링크들을 참조.

라이브러리 및 프레임워크

일반적으로 파이썬을 웹 서비스에 쓴다고 하면 쟁고우(Django, 발음 [ˈdʒæŋɡoʊ])나 플래스크(Flask, 발음 [flӕsk])를 쓴다고 생각하면 된다. 둘의 차이는 풀 스택 웹 프레임워크(Django)이냐 아니냐 정도.

Django

쟁고우(Django)는 Python기반 웹 프레임워크(web framework) 중에 가장 널리 퍼져있다. 풀 스택 웹 프레임워크(full stack web framework)이다.

사용중인 곳

국내에서 Django로 서비스 되는 회사들은 추가바람.

Flask

플래스크(Flask)는 Django와 함께 파이썬에서 많이 쓰이는 웹 프레임워크이다. Django와는 달리 풀 스택 웹 프레임워크(full stack web framework)가 아니다.

여담

파이썬(Python)을 배우면 오픈 소스토어챝(TorChat)의 소스 코드를 수정하여 자신이 원하는 기능을 마음대로 추가할 수 있다.

인터넷상 Python으로 보급되는 package 는 타 어느 스크립트 언어와 비교가 안될 만큼 다양하다. 당신이 하려는 것이 무엇이든, 무슨 언어를 써야 할지 모르겠으면 Python 을 쓰면 된다. Python 으로 직접 만들었던지, 다른 프로그램의 wrapper가 꼭 존재한다. 못하는 것이 없다. PyPI 또는 구글 검색을 해보면 안다. 웹 사이트 서버를 구현하려고 하면 python web framework 를 쳐보자 (Django). 기계학습 알고리즘을 쓰고 쉽다면 python machine learning 이라 검색하자 (scikit-learn). 얼굴인식을 코드 몇줄로 할 수도 있다 (OpenCV). 게임도 만들 수 있다 (PyGame). ~~Python make girlfriend 도 된다 카더라~~

물론 그렇다고 Python 만 쓰는 것이 답은 아니다. 동적 인터프리팅 언어의 한계로 당연히 C, C++ 같은 low-level 언어의 계산속도를 따라갈 순 없으며, 사실 자바스크립트LISP계열 언어 등 동적 언어들을 전체를 주욱 놓고 비교 해봐도 속도가 빠른 편은 아니다. 보통 인터프리터 언어의 속도 문제를 극복하기 위해서 인터프리터에 JIT 컴파일러를 넣는 추세지만 python의 표준인 CPython에서는 구현이 안되어 있다. ~~Pyston 프로젝트가 잘되면 수정바람~~ R 과 같이 특정분야에 특화된 언어와 비교하면 꼭 라이브러리가 더 다양하다고 볼 수도 없다. 이에 대해서 추가바람 그리고 동적 타입 언어(dynamically typed language) 라는 점이 큰 프로젝트에서는 단점으로 작용하여 자료구조 설계나 디버깅이 어렵다는 지적도 있다. 다만 정적 타입 vs. 동적 언어 논쟁은 서로의 장단점이 있으며 일종의 종교논쟁 취급 받는다. 일례로 OCaml같은 강력한 타입 인터페이스(Hindly-Milner)를 가진 경우라 할지라도 타입 에러 정도는 거의 모두 컴파일 타임에 잡아내는 있는 반면에, 모든 버그가 타입 에러는 아니기 때문에 여전히 테스트 및 디버깅 과정은 필요하며, 타입 시스템으로 인한 부담 때문에 빠른 구현에는 부담이 갈 수 있다. 반면에 동적 언어는 빠른 구현의 이점이 있지만 타입 에러가 많이 나는 특징이 있다. 그러나 커버리지가 높은 테스트 세트로 어느정도 커버할 수 있으며 최근의 추세와 부합하는 방식이기도 하다. 마지막으로, Python이 배우기 쉽다고 하지만 결국 도구일 뿐이고, 코딩 자체를 마냥 쉬운 것으로 생각하면 큰코 다친다. 프로그래밍을 할 수 있는 것과 좋게 하는 것에는 큰 차이가 있으며, 좋은 프로그래밍을 하는 것은 프로그래머의 역량에 좌우된다. 특정 언어를 어떻게 돌아가게 짜는 것은 노가다를 배우는 것이라면 프로그램의 설계는 건축가가 거대한 빌딩을 설계하는 작업이라 볼 수 있다. 초가집정도는 단순히 노가다로 해결한다고 해도, 부르즈 할리파는 이런식으로 지을 수 없고 적절한 자재, 외력 등을 고려해서 설계해야 한다. 이렇기 위해서는 알고리즘과 자료구조, 아키텍쳐 등의 공학적 지식과 경험이 있어야 하며, 이런 컴퓨터 엔지니어와 단순 코더가 짠 코드는 생산성, 탄탄함, 버그 발생률, 확장 가능성에서 큰 차이가 난다. ~~그러나 오너 눈에는 똑같은 프로그래머 A,B로 보이겠지~~

빠른 아이디어 구현이 생명인 연구계에서는 각광 받고 있다 (특히 컴퓨터 과학). 연구계에서는 Java 를 제외하면 컴공 외에는 그나마 유일한 경쟁자가 MatLab 이라 볼 수 있는데, 오픈소스가 아니라는 점이 최근 추세와 맞지 않아 입지가 좁아지고 있다. 게다가 패키지 설치를 참 더럽게 이상하게 만들어놨다. Python의 경우는 지원 라이브러리의 대부분이 오픈소스이기 때문에 저장소에서 그냥 커맨드 라인(pip install) 한줄로 필요한 거의 모든 라이브러리를 가져다 쓸 수 있다. 예전에는 한국을 포함하여 대부분의 대학들이 C++ 나 Java 같은 실제 회사에서 많이 쓰는 언어 위주로 수업을 개설했으나, 미국대학들은 개론 수업 언어를 Python 으로 옮겨가는 추세이다 (UC 버클리 컴퓨터과학 개론수업인 CS 61A 를 인터넷 강의로 들어보자!)

여담으로 구글에서 python이라고 검색하면 제일 위에 뜨는 게 위의 바다 괴물이나 뱀이 아니라 이거다.

Python의 창시자 귀도 반 로섬구글에 입사했다. 그리고 Python 은 구글의 3대 개발 언어 중 하나로 알려져 있다.(나머지 2개는 C++Java 이다.) 하지만 최근에 Go로 넘어가려는 움직임이 보인다 카더라. 2012년 12월 7일부로 DropBox에 입사했다.

한 헤드헌터로부터 경력직 파이썬 개발자 취업제안을 받았다고 한다. 즉, 파이썬 창시자에게 파이썬 '경력직' 개발자를 구하는 수준의 메일을 보낸 것(...) # ~~면접관: 파이썬 어느정도 하시나요? 귀도: 제가 만들었는데요.~~

문명 4의 스크립트 언어로 쓰였다. lua와 더불어 게임 스크립트 언어의 양대산맥.

킹덤 언더 파이어의 엔진에도 쓰였다. 500여 개의 자체모듈이 누더기처럼 돌아갔다고 한다(…).

월드 오브 탱크는 상당부분이 파이썬으로 구현되어있다. 유저가 작성하는 모드도 로직 부분은 파이썬으로 구현된다.

EVE 온라인은 Python의 경량/고속 실행 버전인 Stackless Python으로 작성되었다. 개발사 CCP Games는 파이썬 재단의 정식 후원자이기도 하다. 2000년대 초에 싱글코어 CPU가 계속 쓰일 줄 알고 서버 코드를 구버전 파이썬으로 짰다가 다중 코어 사용이 힘들어지자[* 전장에서 일어나는 일을 제외한 나머지 시시콜콜한 일을 다른 코어로 돌리기는 하였으나, 게임의 최소 단위인 전장은 구조상의 한계로 하나의 코어만 동원할 수 있다.], 눈물겨운 마개조를 거듭하여 파이썬이라는 언어가 제공할 수 있는 처리 능력을 한계치까지 뽑아서 쓰고 있다. ~~버그 잡고 최적화하는 프로그래머가 게임 내에서 유명인사가 된 것은 이 게임이 유일하겠지... 이게 다 GIL 때문~~

여기에서 인터프리터 설치 없이 웹 상으로 배워볼 수 있다.

NumPy+SciPy+matplotlib 조합이 과학 공학 계산용으로 써볼만하다는 의견도 있다. ~~조금있으면 독점할 기세이다.~~

2014년 6월 WWDC에서 애플이 공개한 [Swift(프로그래밍 언어)|Swift]]라는 언어에게 220배(...) 느리다고 까였다.[* 하지만, 드롭박스 사에서 개발하고 있는 파이썬을 프론트엔드로 하고, LLVM을 백엔드로 사용하는 Pyston이 릴리즈되면 별차이 없어질 거란 전망도 나왔다.] http://rigvedawiki.net/r1/wiki.php/%EC%8A%A4%EC%9C%84%ED%94%84%ED%8A%B8%28%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D%20%EC%96%B8%EC%96%B4%29?action=download&value=swift_objc_python_comparison.png?width=640

유저들은 C 바인딩인 ctypes를 출동시킨다고 부들부들... 하지만 테스트환경 세팅을 자사 제품에 유리하게 만드는건 벤치마크의 유서깊은 전통이므로 맹신은 금물. 파이썬의 강점은 속도에 있지 않다. 더구나 JIT 없는 동적 인터프리터 언어와 컴파일 언어의 성능을 비교하면 어떤 언어를 비교하더라도 당연히 후자가 압도적으로 유리하다(..)

객체 지향을 배울때 추천할만한 언어이다. 많은 대학들이 C++ 환경에서 가르치지만, 이경우 필요한 객체를 만들어서 쓰는 실습이 많은데 대부분 이미 존재하는 객체를 가져다 쓴다는 개념을 이해하지 못하는 경우가 많다. STL을 쓰면 달라지지만 실습에서 STL을 요구하는 문제가 나오는 경우도 드믈고 주로 사용되는 문자열 변환, 배열 관련 연산 등은 파이썬에서 따로 임포트할 필요없이 자료형 자체가 이미 클래스로서 편리하게 클래스 함수를 던져주기 때문에, 클래스의 재활용이라는 측면을 훨씬 이해하기 쉽다. 무엇보다 하루면 다 배울 수 있는 언어이기도 하고.

14년 8월 30일 유서깊은 파이썬행사인 Pycon이 드디어 한국에서도 성공리에 개최되었다. 내년엔 규모를 더 늘려서 할 거라고 한다. [[2]]