it공부 (개념)/python

__init__? 파이썬 magic method(매직메서드)란?

cantor 2023. 1. 3. 16:32

 

 

Python icons created by Freepik - Flaticon

파이썬에선 class를 통해 객체를 선언할때, 

객체 내부 변수들을 선언하면서 초기화해주는 메서드가 있다. 

    class HelloWorld:

        def __init__(self):
            self.class_variable = 0
    
def는 새로운 함수를 정의할때 사용하는 keyword이다.
그러므로 우리는 __init__ 이라는 이름을 가진 클래스 메서드를 새로 만든것이다.

        import HelloWorld
        
        helloworld = HelloWorld()
        helloworld.__init__()
        
        클래스메서드를 사용하려면 호출을 해줘야한다.
    

..?

조금 이상한점을 느끼지 않았는가? 

우리는, 적어도 나는 객체를 만든후 저런식으로 초기화 메서드를 호출하지 않는다.

다시말하면 __init__은 지혼자 실행된다.

 

진실

파이썬 doc 3.3 magicmethod
A class can implement certain operations that are invoked by special syntax  
클래스는 특별한 문법으로 호출되는 특정 작업들을 실행할 수 있다. 

여기서 말하는 특별한 문법이란?
키워드의 앞뒤에 붙어있는 네개의 언더스코어 ("double underscore", "dunder") 

우리는 그동안 __init__ 이라는이름을 가진 클래스 메서드의 기능을 정의한게 아니다.
이미 있는 기능을 사용하되, 그 기능을 적용할 대상을 지정해준 것이다. 

내함수도 특별해!

우리도 함수명에 "dunder"를 집어넣어도 될까?

이론적으론 그렇다

        def __SayHi__():
            print("hi")
            __SayHi__()
            
        
        출력결과 : hi

파이썬 사회에선 그렇지 않다

파이썬 pep8 naming-convention,Descriptive: Naming Styles 

이름짓기 합의. 기술적: 네이밍스타일 조항의  맨 마지막 항목엔 이런 내용이 있다

__double_leading_and_trailing_underscore__: 
“magic” objects or attributes that live in user-controlled namespaces.
 E.g. __init__, __import__ or __file__. Never invent such names; only use them as documented.
__2개의_언더스코어로_시작하거나_끝나는_메서드__:
 
 유저의 글자가 씌어있는 공간에는 "매직" 객체및 특성들이 거주하고 있습니다.
 절대로 이러한 이름을 만들지 마세요. 문서에서는괜찮습니다.

추가 유용한정보: 소문자 L 대문자 O 대문자 I 도 하나의 변수명으로 사용하지 말라.

결론

나혼자 사용할 프로그램에서의 사용은 괜찮다
하지만 "__" "__"는 파이썬 인터프리터에게 특별한 의미가 있으므로, 당신이 양보해주는것을 권장한다.

 

Ai의 의견

여기까지 포스팅을 작성한 후, "dunder" 의 사용에대해 chat gpt에게 물어보았다.

chat gpt:

"dunder"가 사용되는 함수를 만들거나 실행할때마다 인터프리터에게 혼란을 줄 수있습니다.
클래스 내부에만 사용할 함수가 필요하다면 _my_method 표기법을 권장합니다.
_하나만 사용시, 인터프리터에게 혼란을 주지도않고, import * 에의해 넘어오지도않습니다.
inner class 용 메서드에 적합한 네이밍입니다.

+ @ 잘 알아두고 우리도 파이썬 라이브러리 만들어요!

magic method 의 종류

    • __init__: 초기화 메서드
      객체가 생성시점에서 호출된다. 객체를 초기화한다.



    • __str__: 스트링 표현 메서드.
      특정 객체를 string 형태로 변환하는 역할을 한다.


    • 요즘 웹 BeautifulSoup와 Selenium을 활용한 웹 크롤링을 공부중인데,

 

      .string method를 정의할때 사용한것같아 BeautifulSoup의 소스를 살펴보았다.

있다 !!

 

 

 

    • __repr__: 스트링 표현 메서드
      객체를 기계가 읽을 수 있는 스트링 형태로 변환하는 역할을 한다.



    • __len__: 길이 메서드
      객체의 길이를 반환한다.



    • __getitem__: 아이템 반환 메서드.
      index 연산자 [] 를 통해 객체의 item에 접근한다.
      obj[key]



    • __setitem__: 아이템 설정 메서드.
      index 연산자 [] 를 통해 객체의 item의 값을 설정한다.
      obj[key] = value



    • __delitem__:
      del 연산자를 통해 객체의 item을 삭제한다.
      del obj[key]



    • __contains__: 멤버쉽 검사 메서드
      아이템이 객체에 포함되어있는지 확인한다.
      item in obj



    • __iter__: 반복자 생성 메서드
      객체를위한 반복자 iterator를 생성한다.



    • __next__: 반복자 다음 아이템 메서드.
      현재 반복자의 다음위치의 아이템을 반환하는데 사용된다.





대수 메서드

연산기호 + - * / // % 등의기능을 정의하는데 사용된다.

    • __add__: 더하기 메서드 두오브젝트간 더하기를 정의할때 사용된다. obj1 + obj2
    • 우리는 이미 현실에서도 사용하고있다

 

      행렬의 덧셈은 각 성분끼리 더하는거고, 숫자의 덧셈은 두 숫자만 더하는거다.

 

      똑같아보이지만 다른 연산이다. 계산의 대상이 다르니까 말이다.

 

      파이썬에서 string 끼리더하면 달라붙고, list끼리 더하면 두 리스트를 합친 새로운 리스트가 생성되고

 

      숫자끼리 더하면 덧셈이 실행된다.

 

    
        "hello" + "hi" == "hellohi"

        3 + 5 == 8

        [1,2] + [4, 5] == [1, 2, 4, 5]
        

 

      아마 파이썬 내장함수를 뜯어보면

 

      __add__를 사용하여 위의 세가지 함수가 정의되어있을것이다.
      이내용이 흥미롭다면, 대수학을 공부하자 ㅎㅎㅎ
    • __sub__: 빼기 메서드
      두 오브젝트간 빼기 연산에대해 정의할 때 사용한다.
      obj1 - obj2



    • __mul__: 곱하기 메서드
      두 오브젝트간 곱하기 연산에 대해 정의할 때 사용한다
      obj1 * obj2




    • __truediv__: / 나누기 메서드
      두 오브젝트간 나누기 연산을 정의할때 사용한다.
      obj1 / obj2



    • __floordiv__: // 나누기 메서드
      두 오브젝트간 나누기 // 연산을 정의할때 사용한다.
      obj1 // obj2



    • __mod__: %모듈로 메서드
      % 연산을 정의할 때 사용한다.
      obj1 % obj2

 

 

 

포스팅을 마친다.

 

이번 포스팅에선 chat gpt를 활용해보았다.

 

필자는 chat gpt에게 물어보는내용에대해 공식문서를 항상 다시 찾아본다.

유투브를보면 chat gpt를 극찬하는 내용이 한가득이지만 여전히 제대로된 대답을주는경우가 드물기 때문이다.

 

파이썬 공식문서는 그나마 괜찮다. 하지만 

특정 유명 라이브러리의 오브젝트와 메서드를 설명해달라고하면 

제대로 설명해준적이 없다.

 

수학증명도 마찬가지..

그냥 말하는 구글이다

 

그래도 적극 채용해볼 생각이다.

 

 

 

잘못된 내용이 있으면 댓글로 알려주세요!