개발하는 무민

[python] 매직메서드 (__init__) 본문

Development/Python

[python] 매직메서드 (__init__)

무민_ 2023. 11. 7. 09:34

매직메소드란?

클래스 안에 정의된 함수를 우리는 메소드라고 부른다.

메소드 중에서 __로 시작해서 __로 끝나는 메소드들이 있는데, 이를 매직 메소드 또는 특별 메소드라고 부른다.

 

코드에서 실제로 사용했던 메소드

1) __init__

클래스의 인스턴스가 생성될 때 자동으로 호출되는 초기화 메서드. → 값을 초기화 할 때 사용하는 함수

# 클래스 인스턴스 초기화
def __init__(self):
    self.alink = ''
    self.title = ''
    self.post_id = ''

객체를 초기화할 때 필요한 속성들을 설정하기 위해 이 메서드를 정의한다.

 

더보기

* 클래스와 인스턴스의 차이

클래스는 어떤 객체의 설계도나 틀이고, 인스턴스는 해당 클래스를 바탕으로 만들어진 실제 객체이다.

 

* 컴퓨터에서의 동작과정

1. 메모리 할당 클래스의 인스턴스를 생성하면 컴퓨터의 메모리RAM에 공간이 할당된다.

이 메모리 공간에는 해당 객체의 속성(변수) 값들이 저장된다.

인스턴스화 과정에서 __init__ 메서드가 호출되며, 이 때 정의돤 속성들에 대한 초기값이 설정된다.

 

2. 메서드 실행 인스턴스에는 클래스에 정의된 메서드(함수)를 사용할 수 있는 기능이 있다.

메서드를 호출할 때 해당 메서드 내의 코드가 실행된다.

이 때, 해당 인스턴스의 속성값에 접근하거나 변경할 수 있다.

 

3. 메모리 해제 인스턴스는 더 이상 필요하지 않게 되면 (프로그램 종료 or 인스턴스에 대한 참조가 사라지는 경우 등) 메모리에서 해제될 수 있다. 파이썬에서는 가비지 컬렉터라는 매커니즘이 더 이상 사용되지 앟는 메모리 공간을 자동으로 회수한다.

 

2) __str__

str() 내장 함수가 해당 객체에 대해 호출될 때 실행되는 메서드.

이 메서드는 객체를 문자열로 나타내는 방법을 정의한다.

따라서, 이 메서드를 통해 객체의 문저열 표현을 사용자 정의할 수 있다.

print() 함수를 사용해서 객체를 출력하면, 해당 객체의 __str__메서드가 호출된다.

__str__을 정의하지 않으면 객체를 출력하거나 문자열로 변환하려고 시도할 때 기본적으로 나타나는 것은 객체의 메모리 주소와 같은 기술적인 정보이다.

 

이 메서드를 사용하지 않은 경우

class PersonWithoutStr:
    def __init__(self, name, age):
        self.name = name
        self.age = age

person1 = PersonWithoutStr("Alice", 30)

print(person1)  # 출력: <__main__.PersonWithoutStr object at 0x7f09a3e87a00>

 

 

이 메서드를 사용한 경우

class PersonWithStr:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __str__(self):
        return f"Name: {self.name}, Age: {self.age}"

person2 = PersonWithStr("Bob", 25)

print(person2)  # 출력: Name: Bob, Age: 25

이렇게 __str__ 메서드는 객체를 사람이 읽을 수 있는 형태로 표현하는 데 유용함.

 

언제 매직 메소드를 사용하는가?

파이썬에서 클래스를 사용하면 직접 타입을 만들 수 있다.

리스트, 튜플, 딕셔너리, 정수, 실수, 문자열 등과 같은 타입 역시 클래스를 통해 만들어진 기본 데이터 타입이다.

파이썬에서 순서가 있는 데이터 타입은 대괄호([ ])를 사용해서 인덱싱할 수 있다.

 

내가 직접 만든 타입도 인덱싱 기능을 제공하려면? 매직 메소드를 사용하면 된다.

 

예시)

파이썬에서 문자열 객체에 대해서 덧셈(+) 연산을 실행하면 문자열이 연결된다.

왜? 이는 파이썬 문자열 타입이 덧셈 연산에 대해서 문자열이 더해지도록 정의했기 때문임

 

함수도 객체이다.

파이썬에서 함수의 호출은 함수의 이름에 '( )'를 붙여주면 된다.

왜 '( )'를 붙여주면 함수가 호출되는가? 비밀은 바로 매직 메소드에 있다.

어떤 클래스(타입)의 객체가 있을 때 '( )'를 붙여주면 해당 클래스에 정의된 매직 메소드인 __call__이 호출된다.

 

 

예시)

class MyFunc:
    def __call__(self, *args, **kwargs):
        print("호출됨")

f = MyFunc()
f() # 호출됨

MyFunc 클래스의 객체를 생성하고, 이를 f라는 변수로 바인딩한다고 치자.

그 다음 f() 라고 적는다면 클래스 내에 정의된 __call__을 호출하게 되는것이다.

f는 MyFunc 클래스의 객체이므로, f() 는 MyFunc 클래스에 정의된 __call__ 메소드를 호출하고 그 결과로 '호출됨' 이라는 문자열이 화면에 출력된다.

 

→ 사실 파이썬의 함수는 'function' 클래스의 객체이다.

즉, 함수의 이름은 다음과 같이 function 클래스의 객체를 바인딩하는 변수일 뿐임.

그래서 func( )와 같은 표현을 통해 function 클래스에 정의된 __call__ 메소드를 호출하는 것이다.

 

⇒ 이걸 우리는 함수호출 이라고 부른다.

 

점(.)의 비밀

파이썬에서 객체에 점(.)을 찍으면 해당 객체에 접근이 가능하다. 이것도 역시 매직 메소드 덕분이다.

변수가 어떤 객체를 바인딩하고 있을 때 점(.)을 찍으면 클래스의 __getattribute__ 라는 이름의 매직 메소드를 호출해준다.

(물론 클래스를 만드는 사람 입장에서는 __getattribute__에 적당한 동작을 구현해주는 것이 필요함)

 

예시)

class Stock:
    def __getattribute__(self, item):
        print(item, "객체에 접근하셨습니다.")

s = Stock()
s.data # 객체에 접근하셨습니다.

Stock 이라는 클래스를 정의하고 __getattribute__라는 매직 메소드를 추가한뒤, 객체를 생성한 후 점을 찍고 아무 이름이나 접근해보자.

s.data라고 코딩하면 매직 메소드인 __getattribute__가 자동으로 호출되고 data라는 이름 item이라는 파라미터로 전달됨을 확인할 수 있다.

 

궁금한 점

파이썬에서 클래스를 선언해 타입을 지정하는 방식과,

타입스크립트에서 인터페이스를 정의해 타입을 지정하는 방식이 비슷해보이는데, 차이점이 무엇인가?

 

- 정의

파이썬의 클래스:

  1. 데이터와 기능의 캡슐화: 클래스는 객체 지향 프로그래밍의 핵심 요소로, 데이터와 함수를 하나의 단위로 묶어 관리한다,
  2. 인스턴스 생성: 클래스는 인스턴스화되어 메모리에 저장되며 각 인스턴스는 클래스의 속성과 메서드를 가진다.

타입스크립트의 인터페이스:

  1. 타입 정의: 인터페이스는 타입을 정의하는 주된 방법 중 하나로, 구조적 타이핑을 위한 규약을 제공함.
  2. 코드 재사용: 인터페이스를 다중으로 구현할 수 있으므로 코드의 재사용성을 높인다.
  3. 컴파일 타임 검사: 인터페이스는 런타임에 존재하지 않습니다. 주로 컴파일 시점에서 타입 검사에 사용.

 

- 차이점

  1. 런타임 동작:
    • 파이썬의 클래스: 런타임에 존재하며, 인스턴스를 생성하고 메서드와 속성에 접근할 수 있다.
    • 타입스크립트의 인터페이스: 컴파일 후에 JavaScript 코드에는 포함되지 않고, 컴파일 시점의 타입 검사에만 사용.
  2. 사용 목적:
    • 파이썬의 클래스: 객체의 실제 구현 및 인스턴스 생성에 사용
    • 타입스크립트의 인터페이스: 객체의 구조를 정의, 타입 검사시 사용
  3. 확장성:
    • 파이썬의 클래스: 상속을 통해 확장 가능
    • 타입스크립트의 인터페이스: 다른 인터페이스를 확장하거나 여러 인터페이스를 한 번에 구현 가능
  4. 제한된 구성 요소:
    • 파이썬의 클래스: 속성, 메서드, 생성자 등 다양한 구성 요소를 포함 가능
    • 타입스크립트의 인터페이스: 주로 속성과 함수의 시그니처를 포함한다. 구체적인 구현은 포함하지 않음

요약하면, 파이썬의 클래스는 객체 지향 프로그래밍의 주요 구성 요소로 실제 구현과 객체 생성에 사용되며, 타입스크립트의 인터페이스는 타입 정의와 검사를 위한 도구로 사용된다.

 

 

참고

https://wikidocs.net/83755