[OOP Paradigm] 파이썬객체지향: Everything in Python is an object (2)
Coding/OOP Paradigm

[OOP Paradigm] 파이썬객체지향: Everything in Python is an object (2)

# Everything in Python is an object

파이썬은 순수 객체 지향 프로그래밍 언어이며 모든 것이 객체(object)로 작동됩니다. 앞서 파이썬의 변수는 단순히 포인터라고 이야기하였습니다. 이는 변수 이름 자체에는 첨부된 type 정보가 없다고 생각할 수 있습니다. 이때문에 파이썬을 type-free 언어라고 생각할 수 있지만 사실이 아닙니다. 다음 예시를 보도록 하겠습니다:

>>>> print(type(2))
<class 'int'>
>>>> print(type(2.3))
<class 'float'>
>>>> print(type(2+3j)) 
<class 'complex'>
>>>> print(type("string"))
<class 'str'>
>>>> print(type([]))
<class 'dict'>
>>>> print(type({})) 
<class 'list'>
>>>> print(type(()))
<class 'tuple'>

파이썬에서 클래스 개념의 type 이 존재함을 볼 수 있습니다. 이 때 type 은 변수 이름이 아니라 객체 자체에 연결됩니다. 파이썬과 같은 객체 지향 프로그래밍 언어는 객체를 메타데이터(Meta data)와 기능 (Functionality)를 포함한 entity 로 정의합니다. 파이썬에서는 모든 것이 객체입니다. , 모든 객체는 그의 메타데이터 (attribute)과 관련 기능 (method)를 가지고 있습니다. 이러한 attribute  method 는 점(“.”) 문법을 통해 접근할 수 있습니다.

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

 

이처럼 파이썬에서는 모든 것이 객체로 작동됩니다. 기본 자료형, 클래스, 함수 순으로 객체의 형태를 살펴보겠습니다.

1. 기본 자료형

List 와 같이 복잡한 객체에 대해서만 속성과 메서드가 있을 것으로 생각할 수 있겠지만 파이썬은 간단한 유형에도 속성과 메서드가 속성과 메서드가 연결되어 있습니다. 가장 기본적인 정수형 객체의 type 를 다음 예시로 살펴 보겠습니다.

>>>> import sys
>>>> print(sys.maxsize)
9223372036854775807
>>>> print(type(sys.maxsize))
<class 'int'>
>>>> print(type(sys.maxsize+1))
<class 'int'>

다음과 같이 정수형 자료형 객체도 클래스 ‘int’라는 클래스에 속해 있음을 알 수 있습니다. (참고: 파이썬 3  Int 자료형의 오버플로우를 예방하여 long  int 에 포함됩니다. 파이썬 3 에서는 int 범위를 넘어가는 정수도 type Int 로 취급됩니다.) ‘int’ 클래스에 관해 어떻게 서술하는지 보겠습니다.

>>>> help(int)
Help on class int in module builtins:
class int(object)
| Ifxisnotanumberorifbaseisgiven,thenxmustbeastring,
| bytes, or bytearray instance representing an integer literal in the
| given base. The literal can be preceded by '+' or '-' and be surrounded
| by whitespace. The base defaults to 10. Valid bases are 0 and 2-36.
| Base 0 means to interpret the base from the string as an integer literal.
| >>> int('0b100', base=0)
| __abs__(self, /)
| abs(self)
| ##########생략##########
| ----------------------------------------------------------------------
| Class methods defined here:
| from_bytes(bytes, byteorder, *, signed=False) from builtins.type
| Return the integer represented by the given array of bytes.
| ##########생략##########
| ----------------------------------------------------------------------
| Static methods defined here:
|
|
| __new__(*args, **kwargs) from builtins.type
| Create and return a new object. See help(type) for accurate signature.
| ##########생략##########
| ----------------------------------------------------------------------
| Data descriptors defined here:
| denominator
| the denominator of a rational number in lowest terms
| ##########생략##########

다음과 같이 가장 기본적인 자료형인 int 정수형도 클래스의 기본적인 서술과 더불어 attributes, methods, data descriptor 모두 정의되어 있음을 알 수 있습니다. 이 덕분에 정수형 자료형 객체는 (새로운 함수나 정보를 생성할 필요 없이) 내장된 attribute  method 을 활용하여 여러가지 작업을 수행할 수 있습니다.

>>>> x = 4.5
>>>> print(x.real, "+", x.imag, 'i') #class attribute 4.5 + 0.0 i
>>>> x = 4.5
>>>> x.is_integer() #class method
False
>>>> type(x.is_integer())
builtin_function_or_method

이처럼 파이썬은 복잡한 자료형부터 시작하여 간단한 자료형까지 모든 것이 객체로 이루어져 있음을 알 수 있습니다. 심지어 객체의 속성과 메서드도 자체 type 정보를 가진 객체임을 볼 수 있습니다.

 ✲ 기본 자료형의 메모리 할당(Memory allocation)

기본 자료형의 메모리 할당이 어떻게 되는지 이야기하기 전에 파이썬의 메모리 구조에 대해 이야기해보겠습니다. 오른쪽 그림은 RAM 상의 메모리 구조를 나타낸 그림입니다. RAM 상에서 크게 두 가지 메모리로 나뉩니다. OS 와 기타 앱들, 공유메모리와 이를 제외한 메모리로 나뉩니다. 이 때 맨 밑의 메모리를 제외한 위의 Stack Memory  Heap Memory 에서 메모리 할당이 이루어집니다. x=4 라는 간단한 코드를 실행하였을 때 오른쪽 그림과 같이 Stack Memory  main 공간 위에 변수 x(: 포인터)가 생성되고 이 변수는 Heap Memory 의 해당 객체 와 연결되는 구조를 가지고 있습니다.

, Stack Memory 는 함수가 실행될 때 영역이 생성되며 필요한 변수들이 올라오게 되며, Heap Memory 는 필요한 객체들이 올라오며 포인터로 연결됨을 알 수 있습니다. (다음 메모리 할당 관련 설명부터는 중요하게 작용되는 Stack Memory  Heap Memory 만을 나타냅니다.)

다음 응용 코드와 함께 메모리상에서의 변수 상황을 보겠습니다.

>>>> x = 2.0
>>>> y = x
>>>> if (id(x) == id(y)):
>>>> 	print(“x and y refer to the same object”) 
x and y refer to the same object
>>>> x = x + 1
>>>> if (id(x) == id(y)):
>>>> print(“x and y refer to the DIFFERENT object”)
x and y refer to the DIFFERENT object
>>>> z = 2.0
>>>> if (id(y) == id(z)):
>>>>	print(“y and z refer to the SAME object”)
y and z refer to the SAME object

코드상에서 yzfloat형객체2.0을각각가리키고있습니다.파이썬에서는이둘이동일한객체를나타내므로 포인터 값 또한 동일하게 작용됨을 알 수 있습니다. (파이썬에서 id 라는 함수는 객체의 고유값(레퍼런스)를 나타내는 개념입니다.) 이렇게 간단한 자료형도 객체로 이루어져 메모리 관리가 용이하게 이루어짐을 알 수 있습니다.