변수와 객체

이 노트북은 제이크 반더플라스(Jake VanderPlas)의 A Whirlwind Tour of Python(OReilly Media, 2016)를 기반으로 만들어졌습니다. 이 내용은 CC0 라이센스를 따릅니다. 전체 노트북의 목록은 https://github.com/rickiepark/WhirlwindTourOfPython 에서 볼 수 있습니다.

< 파이썬 문법 빠르게 훑어 보기 | 목차 | 연산자 >

 

이 섹션에서 파이썬 언어의 기본적인 문법을 다루겠습니다. 이전 섹션에 포함된 문법과 조금 다르게 문장이 가지는 의미를 다룹니다. 여기에서 문법과 함께 파이썬에 있는 주요 개념을 살펴보면 이어지는 섹션에 있는 코드를 이해하는데 도움이 될 것입니다.

이 섹션은 파이썬 스크립트 안에서 데이터를 저장하고, 참조하고, 조작하는 주요 도구인 변수객체를 다룹니다.

파이썬 변수는 포인터입니다

파이썬에서 값을 할당하려면 간단히 등호(=) 기호 왼쪽에 변수 이름을 놓으면 됩니다:

# 변수 x에 4를 할당
x = 4

직관적으로 보이지만 이 연산에 대해 잘 못 이해하면 파이썬의 동작 방식이 혼란스러울 수 있습니다. 잠시 좀 더 상세히 들여다 보죠.

많은 프로그래밍 언어에서 변수는 데이터를 담는 콘테이너(container) 또는 버킷(bucket)으로 생각하는 것이 좋습니다. 예를 들어 C에서 다음과 같이 쓰면

// C 코드
int x = 4;

x란 이름의 메모리 버킷을 정의하고 그 안에 4를 넣었습니다. 반대로 파이썬에서는 변수가 콘테이너가 아니라 포인터라고 생각하는 편이 낫습니다. 그래서 파이썬에서 이렇게 쓰면

x = 4

x란 이름의 포인터를 정의하고 값 4를 담고 있는 어떤 다른 버킷을 가리키는 것입니다. 그 결과 파이썬의 변수는 여러 객체를 가리키는 포인터이기 때문에 변수를 선언할 필요가 없고 한 변수가 동일한 타입의 값을 가리킬 필요도 없습니다! 그래서 파이썬을 동적 타입(dynamically-typed) 언어라고도 부릅니다. 즉 변수가 다른 타입의 객체를 가리킬 수 있습니다. 따라서 파이썬에서는 다음과 같이 쓸 수 있습니다:

x = 1 # x는 정수입니다.
x = 'hello' # 여기서는 x가 문자열입니다.
x = [1, 2, 3] # 여기서는 x가 리스트입니다.

정적 타입의 언어를 사용했던 사람들은 C에서 다음과 같은 선언으로 만들어진 타입의 안정성을 그리워할지 모르지만

int x = 4;

동적 타입은 파이썬을 빠르게 작성하고 읽기 쉬운 언어로 만드는 요소 중 하나입니다.

“포인터로서의 변수” 방식으로 가능한 것이며 이를 잘 이해해야 합니다. 변경할 수 있는 객체 하나를 두 개의 변수가 가리키고 있을 때 하나를 바꾸면 다른 것도 바뀌게 될 것입니다! 예를 들어 리스트를 만들고 수정해 보겠습니다:

x = [1, 2, 3]
y = x

같은 객체를 가리키는 변수 xy 두 개를 만들었습니다. 둘 중 하나를 사용해 리스트를 변경하면 다른 변수도 변경될 것입니다:

print(y)
[1, 2, 3]
x.append(4) # x가 가리키는 리스트에 4를 추가합니다.
print(y) # y의 리스트도 변경되었습니다!
[1, 2, 3, 4]

변수를 값을 담고 있는 버킷으로 잘못 생각하면 이런 행동 방식이 혼란스러울 수 있습니다. 하지만 변수를 객체의 포인터로 생각하면 이런 결과가 이해될 것입니다.

x에 다른 값을 할당하기 위해 “=“을 사용해도 y의 값에는 영향을 미치지 않습니다. 할당은 변수가 가리키는 객체를 바꿀 뿐입니다:

x = 'something else'
print(y) # y는 바뀌지 않습니다.
[1, 2, 3, 4]

여기에서도 xy를 포인터로 생각하면 정확합니다. “=” 연산자는 이름이 가리키는 대상을 바꾸는 연산입니다.

이 포인터의 개념이 파이썬의 산술 연산을 복잡하게 만들지 않을까 궁금할 수 있지만 파이썬은 이런 이슈가 없도록 만들어졌습니다. 숫자, 문자열과 그 외 단순한 타입은 변경이 불가능(immutable)합니다. 즉 이런 값들을 바꿀 수 없고 변수가 가리키는 대상을 다른 대상으로 바꿀 수만 있습니다. 예를 들어, 다음과 같은 연산은 아무런 문제가 없습니다:

x = 10
y = x
x += 5 # x의 값에 5를 더하고 다시 x에 할당합니다.
print("x =", x)
print("y =", y)
x = 15
y = 10

x += 5가 호출될 때, x가 가리키는 객체 10의 값을 수정하지 않습니다. 대신 변수 x15의 값을 가진 새로운 정수 객체를 가리키도록 변경합니다. y의 값은 이 연산에 의해 영향을 받지 않습니다.

모든 것은 객체(Object)입니다.

파이썬은 객체 지향(object oriented) 프로그래밍 언어입니다. 파이썬에 있는 모든 것은 하나의 객체입니다.

이 말의 무슨 뜻인지 구체적으로 알아 보죠. 앞서 변수는 단순히 포인터라고 배웠습니다. 변수 이름 자체에는 데이터 타입에 관한 정보가 들어 있지 않습니다. 이 때문에 파이썬이 데이터 타입이 없는 언어라고 잘못 인식됩니다. 하지만 그렇지 않습니다! 다음 코드를 확인해 보죠:

x = 4
type(x)
int
x = 'hello'
type(x)
str
x = 3.14159
type(x)
float

파이썬은 타입을 가지고 있습니다. 타입은 변수 이름에 연결되어 있는 것이 아니고 객체 자체에 연결되어 있습니다.

파이썬과 같은 객체 지향 프로그래밍 언어에서 객체는 데이터와 함께 메타데이터(metadata)와 기능을 가진 엔티티(entity)입니다. 파이썬에서는 모든 것이 객체입니다. 이 말은 모든 엔티티가 일종의 (속성이라 불리는) 메타데이터와 이와 (메서드라 불리는) 연관된 기능을 가지고 있습니다. 이런 속성과 메서드는 점 표기법(dot syntax)으로 참조가 가능합니다.

예를 들어, 앞서 본 리스트에 아이템을 추가하는 append 메서드를 점(“.“) 표기법으로 사용했습니다.

L = [1, 2, 3]
L.append(100)
print(L)
[1, 2, 3, 100]

리스트 같은 복합 객체는 속성과 메서드를 가진다고 기대하는 반면에 파이썬에서는 단순한 데이터 타입도 속성과 메서드가 있다는 것을 예상하지 못하는 경우가 많습니다. 예를 들어, 수치형 타입은 realimag 속성이 있어 복소수를 구성하는 실수와 허수 부분을 반환합니다:

x = 4.5
print(x.real, "+", x.imag, 'i')
4.5 + 0.0 i

메서드는 괄호를 사용하여 호출하는 함수라는 것을 빼면 속성과 같습니다. 예를 들어, 부동소수는 값이 정수인지 여부를 확인하는 is_integer 메서드를 가지고 있습니다:

x = 4.5
x.is_integer()
False
x = 4.0
x.is_integer()
True

파이썬에서 모든 것이 객체라고 했을 때 진짜 ‘모든 것’이 객체임을 말합니다. 심지어 객체의 속성이나 메서드 자체도 자신만의 type 정보를 가진 객체입니다:

type(x.is_integer)
builtin_function_or_method

파이썬의 이런 모든 것을 객체화하는 설계가 매우 편리한 언어로 만들어 줍니다.

 

< 파이썬 문법 빠르게 훑어 보기 | 목차 | 연산자 >

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Google+ photo

Google+의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

%s에 연결하는 중

This site uses Akismet to reduce spam. Learn how your comment data is processed.