Curryingn개의 인자를 가진 함수단일 인자를 가진 n개의 함수 체인으로 만드는 것이다. f(x, y, z)f(x), g(y), h(z)로 분리하는 것이다. 일반적으로 currying은 함수를 반환하는 함수 형태로 구현한다. 따라서 higher-order function이 직/간접적으로 가능한 언어가 currying을 구현하기 편하다. Currying은 특히 Haskell 입문서에서 자주 다뤄진다.

두 예제에서, 위 함수는 두 개의 인자를 한 번에 받아 그 합을 반환하고, 아래 함수는 한 개의 인자를 받아, 남은 인자 하나가 채워지면 합을 반환하는 새로운 함수를 반환한다. 따라서 두 함수는 각각 다르게 호출하게 된다.(sum(1, 3), sum(1)(3))

만약 인자 a에 대한 연산 비용이 비싸고, 인자 b에 채울 값이 지금 당장 없다면, 인자 b에 채울 값이 생길 때까지 시간이 남으므로 위의 커링은 유용할 수 있다. 그러나 위의 경우 인자 a에 대해 연산 비용이 없으므로(별도의 로직을 적용하지 않고 단지 가지고만 있을 뿐이므로), 연산 비용의 분산 면에서는 큰 의미가 없다.

따라서 currying은 함수의 특정 인자에 대해 연산 비용이 비싼 경우, 그 함수에 인자를 나누어 전달하여 함수의 로직을 점차적으로 수행할 때에 유용하다. 다만 내 경우에는 함수 자체가 계산 비용이 비싼 경우는 있었어도, 함수의 특정 인자에 한정되어 계산 비용이 비싼 경우는 없었기에 이런 상황이 그리 많지 않았고 따라서 메모이제이션으로 충분히 처리할 수 있는 경우가 더 많았다.

이에 더해 인자 a, b 간의 양방향 의존성이 있다면 currying을 적용하기 더 어렵다. 단지 인자 a가 인자 b에 단방향 의존한다면, 인자 b를 먼저 받아 로직을 일부 처리하고 인자 a가 채워질 때 클로저로 인자 b에 접근해 나머지 로직을 처리하면 된다. 그러나 애초에 두 인자가 같이 필요한 로직 뿐이라면 currying의 중간에 인자 여러 개를 받는 함수를 끼워두거나 애초에 a와 b 인자 모두가 채워졌을 때 로직을 수행하는 등의 방식으로 해결한다. 내 경우에는, currying을 Python의 ORM 라이브러리인 SQLAlchemy에서 read db와 write db에 대한 connection을 관리하기 위한 context manager 함수를 정의하는 데에 사용한 적이 있다.

위의 경우 read_session_factorywrite_session_factory는 session 함수의 engine_name에 각각 'read'와 'write'를 전달하여 반환받은 새로운 함수다. 그러나 engine_name 인자는 연산의 양에 큰 영향을 끼치지 않으므로, 그냥 함수로 분리해 내더라도 성능 상에 큰 문제가 생기지 않는다.

프론트엔드 API에서 자주 쓰이기도 하고, Go 내부 라이브러리에도 커링된 함수가 몇 가지 있다고 하지만 사실 이런 커링 기법을 완전히 적용할만한 경우를 찾지는 못했다. 하지만 이런 방식의 함수 작성은 함수형 프로그래밍과 클로저 등에 대한 개념을 강화하는 데에 도움을 주는 것은 맞는 것 같다.

'프로그래밍 > 언어론과 비슷한' 카테고리의 다른 글

Higher-order function  (0) 2019.02.06
Memoization  (0) 2018.09.11

Higher-order function은 Kotlin을 배우면서 마주친 개념이었다. 사실 higher-order function 자체는 이전에 내가 배웠던 다른 언어에서도 사용되던 개념이었는데, Kotlin 이전까지는 이에 대해 따로 설명을 하던 튜토리얼이 없었어서 Kotlin에서 처음으로 알게 되었다. Higher-order function은 고차함수, 또는 고계함수로 번역하며, 아래 두가지 중 하나 이상을 만족하는 함수를 의미한다.

  • 함수를 파라미터로 전달받는 함수
  • 함수를 리턴하는 함수

정의 자체가 그리 어렵지 않다. 그리고 함수가 값으로서 평가되기만 하면 사용할 수 있는 개념이라 일급 객체로서의 함수가 지원되는 언어는 higher-order function이 가능하다. 따라서 웬만한 프로그래밍 언어들에서 어렵지 않게 마주칠 수 있다. 아래는 Python의 예다.

위의 sum 함수는 덧셈 연산의 피연산자 a, b와 결과를 전달받을 함수인 callback을 인자로 받는다. 함수를 파라미터로 전달받으므로, 위 함수는 higher-order function이다.

위는 파이썬 데코레이터의 기본형이다. timeit 함수는 인자로 함수를 받고, wrapper 함수를 반환한다. 두 조건을 모두 만족하므로, 당연히 이도 higher-order function이다.

JavaScript도 함수가 값이기 때문에, higher-order function을 표현할 수 있다.

'프로그래밍 > 언어론과 비슷한' 카테고리의 다른 글

Currying  (0) 2019.02.08
Memoization  (0) 2018.09.11

이제 연산자라는 개념을 이야기한다. 연산자는 크게

  • 사칙연산을 위한 산술 연산자
  • 대소나 항등 평가 등 비교를 위한 관계 연산자
  • 불린 값을 피연산자로 두어 논리 연산을 하기 위한 논리 연산자
  • 하나의 피연산자에 대한 증가/감소를 위한 증감 연산자

로 나뉜다. 이번에는 이들 중 산술 연산자에 대해 알아볼 것이다.

산술 연산자

산술 연산자는 두 개의 값을 피연산자로 사용하고, 하나의 결과를 반환한다. 두 개의 항에 대해 적용되는 연산이므로, 이항 연산자라는 범주에 속한다. 사칙연산에 쓰이는 덧셈(+), 뺄셈(-), 곱셈(*), 나눗셈(/)표준 산술 연산자라고 부르고, 파이썬은 여기에 더해 문법적으로 몇가지 연산자를 더 지원하고 있다. 아래 코드는 표준 산술 연산자에 대한 내용이다.

수학에서 이야기하던 것처럼 n과 0을 곱한 결과는 0이고, 0을 n으로 나눈 결과는 0이다. n을 0으로 나누는 일은 불가능하므로 에러가 발생한다. 여기서 주목할 점은 덧셈, 뺄셈, 곱셈에 대해서 int와 float 간의 연산 결과는 float이며, 나눗셈의 경우엔 나누어 떨어지더라도 연산 결과가 float이라는 점이다. Python 2는 조금 다를 수 있다.(나눗셈 연산의 결과가 무조건 int) 나중에 가서 헛갈리는 경우가 간혹 있으니, 숙지하고 있는게 좋다.

표준 산술 연산자가 아닌 연산자들을 알아보도록 하자. 나머지(%), 거듭제곱(**), 소수점 버림 나눗셈(//)이 있다.

이것도 수학에서의 이야기와 동일하게, n의 0제곱은 1이다.

'프로그래밍 > Python' 카테고리의 다른 글

숫자 자료형과 리터럴  (0) 2019.01.25
파이썬의 타입 시스템과 빌트인 타입, 변수 선언  (0) 2019.01.23
주석  (0) 2019.01.07
Hello World, 세미콜론은 optional하다?  (0) 2019.01.03
개요와 설치  (0) 2019.01.01

숫자(number) 타입은 타입 개념의 가장 기본이 되는 자료형이다. 파이썬은 복소수(실수와 허수) 전체에 대해 빌트인 타입이 존재한다. Java와 같이 주류 프로그래밍 언어들 중 빌트인 숫자 타입에 허수부를 지원하지 않는 것들도 있으므로, 특별하다고 느껴질 수도 있다. 파이썬의 숫자 타입은 정수, 소수, 복소수 타입으로 나눌 수 있다.

정수(int)

수학에서 말하는 것처럼, 양의 정수, 음의 정수, 0을 다룬다. 별도의 최대값은 없다.

정수 리터럴

먼저, 음의 0(-0)은 없다. 당연한 논리지만, JavaScript에는 실제로 양의 0과 음의 0이 나뉘어 있기 때문에 언급하게 됐다.

파이썬의 정수 리터럴은 2진수, 8진수, 10진수, 16진수 표현이 가능하다. 10진수가 아닌 정수 리터럴을 정의하는 경우, 0 뒤진법에 해당하는 영어 명칭의 첫 글자(b(binary), o(oct), x(hex))를 명시한 후 값을 정의하면 된다. 그 예는 다음과 같다 : 0b110, 0o15, 0xF1F

가독성을 높이기 위해 리터럴에 언더스코어를 사용할 수 있다. 5000050,000으로 표기하는 것과 같은 맥락이다. leading, tailing, doubly 형태를 제외하고는 자유롭게 사용 가능하다. 예를 들어, _123, 123_, 12__3은 불가능하고, 12_3_456_7은 가능하다. 표기 상의 sugar일 뿐이므로, 실제로는 언더스코어가 제거된 상태로 다뤄진다.

소수(float)

소수부가 있는 수이다. 이전 글에서도 말했듯, 파이썬은 소수를 위한 타입으로 float만을 사용한다. 파이썬 버전마다 다르긴 하겠지만, 내가 사용하고 있는 Python 3.6.5에서는 소수 리터럴이 소수점 아래 15자리까지 표현할 수 있다.

소수 리터럴

e 표기법(지수 표현)을 사용할 수 있다. 그러나 음의 0이 없는 것과는 다르게 음의 0.0이 존재한다. 부동소수점을 사용하기 때문이다. 0이나 0.0의 지수 표현 결과는 0.0, -0이나 -0.0의 지수 표현 결과는 -0.0이 된다.

복소수(complex)

수학 기준으로는 복소수가 실수와 허수를 모두 포함하므로 complex 타입이 int나 float이나 모두 표현할 수 있다고 생각할 수 있으나, 여기서는 단지 허수부가 들어 있는 숫자를 다루기 위한 타입 수준으로만 생각하면 된다. 통계나 데이터 과학에 관련된 니즈가 많은 언어라 그런지는 몰라도, 빌트인으로 복소수 타입을 지원한다. 객체의 property로 실수부/허수부를, 절대값을 반환하는 빌트인 함수인 abs()에 넘기면 복소수의 크기를, conjugate 메소드를 통해 켤레복소수를 알아낼 수 있다.

복소수 리터럴

소수부+허수부 또는 허수부만으로 이루어지며, imaginary number의 약자 i 대신 j를 사용한다. 4번 라인부터는 파이썬의 복소수 타입 지원에 대한 추가적인 예제일 뿐이므로 프로퍼티, 함수, 메소드 개념을 이해하기 어렵다면 1, 2번 라인만 봐도 무방하다.

'프로그래밍 > Python' 카테고리의 다른 글

산술 연산자  (0) 2019.01.28
파이썬의 타입 시스템과 빌트인 타입, 변수 선언  (0) 2019.01.23
주석  (0) 2019.01.07
Hello World, 세미콜론은 optional하다?  (0) 2019.01.03
개요와 설치  (0) 2019.01.01

변수(variable)는 데이터의 실제 위치와 매핑되어 있는 상징적인 이름이다. 어떠한 값에 대한 참조를 가지고 있기 때문에, 특정 값을 계속해서 유지시키기 위해 사용할 수 있어 매우 중요하다. 파이썬은,

  • 런타임에 자료형을 검사하는 동적 검사
  • 이미 특정 자료형으로 정의된 변수에 다른 자료형의 값을 할당할 수 있는 동적 타이핑
  • 인터프리터가 자료형을 추론하여 알맞는 타입을 알아서 준비하는 타입 추론 또는 암시적 타입 선언(implicit type declaration)
  • 암시적 형변환(implicit type conversion)이 지원되지 않아 런타임에 타입 오류를 만나면 에러가 발생하는 강타입 언어다.
  • 이 정도가 파이썬 타입 시스템의 큰 틀이다. 이것저것 어려운 말들 많지만, 아래와 같은 코드를 작성할 수 있다는 것이다.

    인터프리터가 타입을 추론해 주기에 타입을 명시하지 않아도 되고, 동적 타이핑이 지원되기에 정수 타입의 값이 할당되어 있던 변수에 다른 타입의 값을 재할당할 수 있게 된다. 같은 동적 타이핑 언어들과 다르게, 변수 선언에 별도의 키워드(var, let 등)도 필요하지 않다. 타입 시스템 이야기는 짧게 여기서 마무리하자.

    타입과 파이썬 빌트인 타입

    컴퓨터는 전기로 작동한다. 이러한 전기 신호의 on을 1에, off를 0에 대응하고 이들을 조합한 일련의 신호는 10110110...처럼 표현할 수 있다. 이러한 숫자 체계를 수학에서는 이진수라고 하고, 이를 간단한 공식에 대입하여 우리가 흔히 이해하는 10진수로 바꿔서 표시(1101 -> 13)할 수 있다. 0과 1로 만들어지는 값은 결국 수(number)일 뿐이지만, 우리가 현실에서 마주칠 수 있는 데이터들은 수 개념에서 한정되지 않는다. 따라서 컴퓨터 과학에서는 이진수의 조합에 기술적인 기준 몇 가지를 더해 정수와 실수, 문자열 등을 구분하도록 하고 있으며, 일반적인 프로그래밍 언어들도 이러한 체계를 따르고 있다. 이들을 자료형(type)이라고 부른다.

    파이썬에서 제공하고 있는(built-in) 자료형은 크게 기본 자료형컨테이너 자료형으로 나뉜다. 기본 자료형은 아래와 같다.

    • 정수(int) : -1, 0, 1 등
    • 소수(float)복소수(complex) : 1.2, -0.8, 9i+1 등
    • 문자열(string) : 'a', 'hello', '' 등
    • boolean : True, False
    • None : 값이 없음을 의미

    다른 프로그래밍 언어들에서도 사용되는 기초적인 타입들이다. 조금 특별한 점은, 다른 언어처럼 소수 타입이 float와 double의 두가지로 분류되어 있지 않다는 것과, 문자(character)와 문자열(string)을 문자열 타입 하나로 표현하고 있다는 것이다. 그리고 이러한 타입의 데이터들을 조합하여 하나의 단위로 묶어서 다루는 컨테이너 타입들이 있다.

    • 리스트(List) : [1, 2, 3, 4]
    • 튜플(Tuple) : (1, 2, 3, 4)
    • 사전(Dictionary) : {'a': 1, 'b': 2}
    • 집합(Set) : {1, 2, 3, 4}

    이들은 논리적으로 데이터 타입인 동시에 자료 구조 ADT의 구현체기도 하다.(list는 append와 pop으로 스택의 push/pop을 구현하고 있는 등..)

    변수

    a라는 변수를 선언하며, 숫자 리터럴을 a에 할당(assign)했다. 어떤 값을 '직접 써서 표현하는 것'리터럴이라고 한다. 수학에서의 등호는 '같음'을 의미하나, 컴퓨터 과학에서의 등호는 '할당'을 의미한다. 그리고 이 할당의 방향은 오른쪽에서 왼쪽이다. 따라서, 등호를 기준으로 우변이 평가되고, 평가된 값이 좌변에 할당된다. 따라서 변수 a는 타입이 추론되어 정수 타입이 되고, 값으로 1을 가지고 있게 된다. 아래의 할당문을 보면 우변 평가, 좌변 할당이라는 순서를 조금 더 쉽게 이해할 수 있다.

    연산자 개념이 등장했지만, 수학적으로 이해하면 된다. 우변인 3 * 5 + 2가 평가되어 17이 되고, 좌변인 a에 할당되어 결론적으로는 a에 17이 할당된다. 우변에 들어간, 값들과 연산자를 함께 사용하여 수식을 표현한 것을 표현식(expression)이라고 한다. 그 자체로 평가되어 하나의 결과값으로 축약되므로, 이를 평가식이라고도 한다. 리터럴로 값을 표현해놓은 것 그 자체도 expression이 될 수 있다. 아무튼 표현식은 쉽게 보면 '간단한 수식'이지만, 언어 구조의 근간을 이루는 매우 중요한 개념이므로 숙지하고 있는 것이 좋다.

    파이썬은 아래처럼 변수에 대해 몇가지 트릭을 사용할 수 있다.

    1번 라인은 동일한 값을 가진 여러 개의 변수를 선언하는 것, 2번 라인은 서로 다른 값을 가진 변수 여러 개를 인라인으로 선언하는 것이다. 2번 라인은 사실 tuple 표현식과 unpack을 응용한 건데, 이건 나중에 알아보도록 하자. 아무튼, 이런 게 가능하다.

    파이썬의 타입 시스템부터, 빌트인 타입과 변수 개념을 알아봤다. 다음 글부터는 자료형 위주의 이야기들을 채울 예정이다.

    '프로그래밍 > Python' 카테고리의 다른 글

    산술 연산자  (0) 2019.01.28
    숫자 자료형과 리터럴  (0) 2019.01.25
    주석  (0) 2019.01.07
    Hello World, 세미콜론은 optional하다?  (0) 2019.01.03
    개요와 설치  (0) 2019.01.01

    주석(comment)은 설명문이다. 문학 책에 실려 있는 소설에서, 어려운 단어가 나오면 페이지의 맨 밑에서 뜻을 풀어 알려주는 것처럼 말이다. 남이 짠 코드를 본 적이 있거나, 내 코드를 남이 본 경험이 있다면 주석이 왜 중요한지 알 것이다. 코드의 이해를 돕기 때문이다. 주석으로 나쁜 코드를 회피하지 말라고 하지만, 아무리 가독성에 신경쓴다고 하더라도 코드의 복잡도가 늘어나면 주석 없이는 의도를 파악하기 힘들기 마련이다.

    대부분의 프로그래밍 언어들은 일반적으로 한 줄짜리 주석에 slash(/)를, 여러 줄짜리 주석에 slash와 asterisk(*)를 섞어 사용한다. Java의 예를 보자.

    그리고 아래는 Python의 예다.

    한 줄짜리 주석에는 내용의 맨 앞에 sharp(#) 기호를 사용하고, 여러 줄짜리 주석에는 내용에 세 개의 double quote(""")를 감싸 표현한다. 대부분의 경우 #을 사용하는 전자의 표현식을 사용한다. 참고로 쉘 스크립트Ruby에서 주석을 #으로 표현한다.

    후자의 주석 표현에서 사용하는 세 개의 double quote로 감싸진 문자열은, 사실 파이썬에서 문자열 리터럴 표현식이기도 하다.(파이썬에는 4가지의 문자열 리터럴 표현식이 있다 : ', ", ''', """) 따라서 값으로써 관리하기에 더 유연하기 때문에, 파이썬에서는 이를 함수나 클래스 정의의 맨 위에 사용하여 docstring(문서화 문자열)이라는 이름의 주석으로 사용하도록 권고한다. 실제로 #을 사용한 주석은 런타임으로 넘어가며 무시되지만, """를 사용한 주석은 런타임에서도 그대로 유지된다. 결론은, 여러 줄에 걸쳐 주석 처리를 하는 것을 포함한 일반적인 경우에는 #을 사용하는 것이 좋다는 것이다.

    '프로그래밍 > Python' 카테고리의 다른 글

    산술 연산자  (0) 2019.01.28
    숫자 자료형과 리터럴  (0) 2019.01.25
    파이썬의 타입 시스템과 빌트인 타입, 변수 선언  (0) 2019.01.23
    Hello World, 세미콜론은 optional하다?  (0) 2019.01.03
    개요와 설치  (0) 2019.01.01

    이번에는 "Hello World"라는 문자열을 콘솔에 출력하는 방법과, 파이썬에서 세미콜론의 용도에 대해서 알아보고자 한다.

    Hello World

    파이썬에는 글로벌 네임스페이스에서 빌트인 함수들이 여럿 지원된다. List 자료형의 요소를 정렬한 결과를 반환하는 함수도 있고, 요소를 뒤집은(reversed) 결과를 반환하는 함수, 숫자의 절대값을 반환하는 함수, 그리고 파이썬 3.7에서는 디버깅을 위해 break point를 걸어주는 함수도 생겨났다. 콘솔 출력을 위해선 빌트인 함수들 중 print를 사용하며, 파이썬의 빌트인 함수들은 공식 문서에서 확인할 수 있다. 최근부터 한국어 문서화가 잘 진행되고 있어서 편하다.

    print 함수의 시그니처는 print(*objects, sep='', end='\n', file=sys.stdout, flush=False)인데, 'Hello World'를 출력하기 위해서는 기본값이 정의되어 있는 sep, end 등의 인자는 아직 신경쓸 필요 없고, *objects 부분만 이해하고 있으면 된다. 파이썬에서는 가변 인자(variable argument)를 위해 * 기호를 쓰므로, 여러 값을 한 번에 출력할 수 있다는 것을 의미한다.

    위 두 개의 print문의 결과는 동일하게 'Hello World', 그리고 개행이다. print 함수는 인자로 전달된 objects를 하나씩 출력할 때, sep에 지정되어 있는 문자열이 사이사이에 들어가기 때문에 2번 라인의 결과도 'Hello World'가 된다. sep을 바꾸면 어떻게 될까?

    'Hello'와 'World' 사이에 sep인 ', '가 포함되어, 결과는 'Hello, World'가 된다. 참고로, 파이썬은 위처럼 인자를 '선택'하여 값을 전달할 수 있다. 키워드 인자라고 부른다.

    파이썬에서의 세미콜론

    일부 가이드에서는 파이썬에서 세미콜론은 optional(선택적)이라고 이야기하나, 잘못된 설명이다. '세미콜론이 optional하다'라는 설명은 '써도 되고, 안 써도 된다'라는 이야기이므로 JavaScript에 어울린다.

    세미콜론을 붙이던, 붙이지 않던 상관 없다(일부 버전에서는 그렇지 않을 수도 있다). 파이썬에서 세미콜론은 단지 여러 statement를 한 줄에 이어서 사용할 때만 쓸 수 있다.

    '프로그래밍 > Python' 카테고리의 다른 글

    산술 연산자  (0) 2019.01.28
    숫자 자료형과 리터럴  (0) 2019.01.25
    파이썬의 타입 시스템과 빌트인 타입, 변수 선언  (0) 2019.01.23
    주석  (0) 2019.01.07
    개요와 설치  (0) 2019.01.01

    Python 카테고리를 새로 생성했다. 언어론을 조금 배우며 더 나은 설명이 떠오른 부분도 많았고, 입문자를 너무 고려한 탓에 어려운 개념을 일부 배제하느라 제대로 설명하지 못한 부분도 있었다. Python-New 카테고리는 파이썬에 대해 조금 더 확실하고 명쾌한 설명을 블로그에 올리기 위해 생성하게 됐다. 기존 파이썬 카테고리와 설명이 일부 겹칠 수도 있으나, 적어도 설명이 줄어들진 않을 예정이다.

    Java, C# 등 대부분의 주류 프로그래밍 언어들처럼 Python도 C로 구현되었다. Python은 아래와 같은 특징을 가진다.

    • 오픈 소스
    • 인터프리터
    • 별도의 entry point가 없는 스크립트 언어
    • 동적 검사, 암시적 형변환이 없는 강타입, 동적 타이핑
    • 암시적 타입 추론
    • 타입 명시를 지원
    • 멀티 패러다임이면서, class로 객체지향을 표현. 다중 상속 허용
    • 연산자 오버로딩 존재
    • Reference counting과 가비지 컬렉션 기반의 메모리 관리
    • 공식 코드 컨벤션 가이드라인 존재(PEP8)
    • optional한 세미콜론(그러나 자바스크립트 스타일의 optional과는 조금 다름)
    • 대부분의 프로그래밍 언어들처럼, Lexical(정적) scoping
    • function level scoping
    • 의존성 관리와 가상 환경 구성에 대한 지원이 npm만큼 강력

    그리고 파이썬의 높은 생산성에 도움을 주는 몇가지 syntatical sugar와 기능들이 존재한다.

    • for statement는 foreach로만 사용 가능
    • 비교 연산자 chaining 가능(a < b < c)
    • switch가 없음
    • 가독성을 위해, 논리 연산자에 기호가 아닌 키워드를 사용(&&를 and로, ||를 or로, !를 not으로)
    • 매직 메소드로 인해 생겨나는 강력한 데이터 모델
    • 매우 큰 라이브러리 생태계
    • Glue language라는 개념을 통해, 타 언어와의 바인딩이 쉬움

    문화, 강력한 직관성

    내가 파이썬을 좋아하는 이유는, 바로 '가장 아름다운 하나의 답이 존재한다'라는 명제와 코드가 영어 아티클처럼 읽히는 강력한 직관성 때문이다. 높은 생산성과 가독성이 나오는 것도 이 때문이다. 인간의 생각을 코드로 가장 쉽게 표현할 수 있도록, 파이썬은 '쉬운 언어'로 진화해 왔다. PEP8이라는 스타일 가이드에 의해 코드 스타일도 단 하나의 스타일로 진화되어 왔다. JavaScript 진영에서 수많은 코드 스타일이 존재하는 것과 사뭇 다르다. '정해진' 것들이 있기 때문에 선택지는 좁을지 몰라도, 가이드라인만 따르면 코드를 확실하게, 정교하게, 가독성 높게 작성할 수 있다.

    또한 언어 자체가 웬만하면 가독성이 높을 수밖에 없게 설계되어 있다. 아래의 코드 스니펫을 보면 파이썬이 얼마나 직관적인지 알 수 있다.

    파이썬은 쉽다?

    파이썬은 쉬운 게 맞다. 진입장벽이 낮기도 하고, 애초에 '쉬운 언어'를 만들고자 하는 의도로 만들어진 언어기 때문이다. 그러나 잘 쓰기는 어렵다. 예를 들어, 숫자들이 공백으로 구분되어 있는 문자열에서 최소값을 출력하는 코드는 아래와 같이 작성할 수 있다.

    이 코드는 아래처럼 개선할 수 있다.

    아래와 같은 방법도 있다.

    발상의 전환이나, '이 코드가 최선인가'하는 압박이 다른 언어들보다 더 많아서, 번아웃이 오는 빈도도 많다. 따라서 우리가 취해야 할 폼은, 책 하나 다 읽었다고 '다 끝났다'라는 생각을 하지 말아야 하는 것이다. 적어도 프로그래밍 언어를 '다 안다'라고 할 수는 없으니 말이다.

    구현체

    Python에는 여러 구현체들이 있다. 다른 언어를 하던 프로그래머 입장에서는 'Java 7, 8, 9같은 차이겠거니' 할 수 있다. 그러나 여기서 이야기하고자 하는 건 표준 배포판인 CPython이 C로 개발되는 것과 다르게, 아예 다른 프로그래밍 언어를 이용해 구현된 파이썬이다. 이게 다 파이썬이 오픈소스여서 가능한 일이다. 파이썬 배포판의 대부분도 오픈소스로 개발되고 있다.

    CPython

    '파이썬'이라고 하면 대부분 CPython을 뜻한다. 파이썬 재단에서 인정하는 표준 구현체이며, python.org에 들어갔을 때 보이는 예제들이나 'Download Python'도 CPython을 기준으로 한다. Python 코드를 바이트코드로 컴파일하고, 그 결과를 VM이 해석하는 방식을 사용한다.

    Cython

    정적 컴파일러 최적화다. Type mixin이라는 개념을 통해 C나 C++ 모듈로 컴파일한다.

    IronPython

    .NET FrameworkMono 기반에서 작동할 수 있도록 C#으로 개발된 파이썬이다.

    Jython

    JVM 기반에서 작동할 수 있도록 Java로 개발된 파이썬이다.

    배포판

    이것도 다른 언어를 하던 프로그래밍 입장에서는 이해하기 어려울 것이다. 파이썬은 사용하는 대상의 스펙트럼이 매우 넓기에(머신러닝, 웹 서버, 데이터 분석 등) 특정 집단을 타겟으로 하는 별도의 배포판이 존재한다. 데이터 과학을 위한 Anaconda, ActivePython, Enthought Canopy, WinPython 등이 그 예다.

    설치

    Java 8, 9, 10처럼, 파이썬도 버전 개념이 존재한다. Python 2Python 3가 대표적인 메이저 버전이다. 별다른 이유가 없다면, Python 3을 사용하는 것이 좋다. 애초에 Python 3가 Python 2에서 지적된 여러 단점들을 제거하기 위해 만들어졌기 때문이다. Python 3가 나온 지 얼마 안 됐던 때에는 대부분의 라이브러리가 Python 2만을 지원했었기에 Python 3를 꺼려하는 개발자가 많았지만, 요새는 그런 경우가 거의 없다.

    Windows

    Windows의 경우에는 공식 페이지인 python.org에서 설치할 수 있다. 별도로 설정을 건드리지 않으면 PATH도 알아서 잡아 주므로 터미널에서 python 명령을 입력했을 때 인터프리터가 정상적으로 동작하면 설치에 성공한 것이다.

    $ python
    

    Mac

    Mac은 Linux 기반의 운영체제기에, 기본적으로 파이썬이 설치되어 있다. Mac을 비롯한 리눅스, 또는 리눅스 기반 운영체제들은 Python 2와 Python 3를 별도로 관리함에 주의해야 한다. 터미널을 기준으로 하면, Python 2는 python, Python 3는 python3 명령을 사용한다.

    $ python
    $ python3
    


    '프로그래밍 > Python' 카테고리의 다른 글

    산술 연산자  (0) 2019.01.28
    숫자 자료형과 리터럴  (0) 2019.01.25
    파이썬의 타입 시스템과 빌트인 타입, 변수 선언  (0) 2019.01.23
    주석  (0) 2019.01.07
    Hello World, 세미콜론은 optional하다?  (0) 2019.01.03

    '프로그래밍 > 언어론과 비슷한' 카테고리의 다른 글

    Currying  (0) 2019.02.08
    Higher-order function  (0) 2019.02.06

    + Recent posts