Python: self and magic methods

xsldihsl·2024년 2월 19일

Python

목록 보기
1/5

Contents

  1. self 의 개념
  2. init
  3. Class vs Instance variables
  4. name, main
  5. VS Code vs Pycharm

1. self 의 개념

self 는 해당 class 안에 있는 variable 을 implicitly refer to 해주기 위해 사용한다.

다음의 class Monster() 예시를 보자.

class Monster():
	hp = 100
    alive = True
   
    def damage(self, attack):
    	self.hp = self.hp - attack
        if self.hp < 0:
        	alive = False

	def check_status(self):
    	if self.alive:
        	print('Alive!')
        else:
        	print('Dead!')

# monster instances
 m1 = Monster()
 m1.damage(120)
 m1.check_status()

 m2 = Monster()
 m2.damage(40)
 m2.check_status()     

위의 코드를 통해 게임 상에서 괴물을 공격하고자 할 때 하나의 해당 괴물에 대한 hp (health point) 를 체크해 괴물이 죽었는지 살았는지에 대한 정보를 알 수 있다. 깔끔하게 잘 짜여진 코드같아 가져와봤다.

마지막 부분을 보면 m1 과 m2, 두 개의 instances 가 만들어졌다.

이후 m1 과 m2 가 각각 Monster class 에 속하는 self variables 그 자체로서 damage() 와 check_status() 함수들에 들어감을 알 수 있다. 참고로 위의 코드를 적다보면 def 의 parameters 에 저절로 self 가 채워지는데, 이처럼 class 안에 있는 함수들은 모두 self 를 첫 parameter 로 갖게 된다.

단, m1.damage(120) 에서도 볼 수 있듯이 함수를 이용할 때 self 의 자리는 놔두도록 한다.


2. init

그동안 애매모호했던 init function 의 개념이 조금은 명확해진 것 같다.

class test:

    def __init__(self, a, b):
        self.x = a
        self.y = b

이와 같이 init 은 어떠한 class 내에서 instance variables 에 대한 값을 initialize 해주는 함수이다. 그렇다면 instance variable 은 무엇인지 class variable 과 비교하여 좀 더 자세히 알아보자.


3. Class vs Instance variables

class variable 은 모든 instance 끼리 공유하는 static 한 값인 반면에 instance variable 은 해당 함수 안에서 init 을 이용해 값이 initialize 되는 variable 이다.

class Dog 에 관한 예시를 들어보겠다.
강아지는 다리가 4개, 꼬리가 1개이므로 이는 static 한 변수이다.

class Dog:
	# class variables
    legs = 4
    tail = 1
   
    def __init__(self, name, age):
    	self._name = name
        self._age = age

# Dog instances
dog1 = Dog('max', 5)
print(dog1._name) # -> max
print(dog1._age) # -> 5

dog2 = Dog('roy', 12)
print(dog1._name) # -> roy
print(dog1._age) # -> 12

이렇듯 dog1 과 dog2 는 다른 이름과 나이를 갖는데 이는 _name 과 _age 가 instance variables 로 initialize 되었기 때문이다.

print(dog1.legs) # -> 4
print(dog2.legs) # -> 4

반면, legs 는 class variable 로서 instances 와는 independent 하게 값의 변화가 없음을 알 수 있다.


4. name, main

앞서 배운 init 과 같은 함수들을 python 에서는 magic methods 라고 한다. 또 다른 magic methods 로는 name 과 main 을 들 수 있다.

name 과 main 의 가장 핵심적인 부분은 python 코드가 직접 작성된 파일 자체에서 run 되는지, 아니면 import 된 파일에서 실행되는지의 구분이다.

  • Recall: C
# include <stdio.h>
void main(void)
{
...
}
  • Recall: Java
public class Hello_World
{
	public static void main(String args[])
    {
    ...
    }
}

오랜만에 예전에 사용했던 CJava 의 기본 틀을 가져와봤다.

Python 또한 main 을 갖고 있지만 위의 C 또는 java 처럼 explicit 하지 않다.

if __name__ == "__main__":
	print(__name__)

이 조건문을 보면 name 이 main 과 같다면 name 을 프린트 할 수 있다.

name 은 현재 module 의 이름을 담고 있는 variable 이다.

따라서, 이 python module 이 직접 실행된다면 name 은 main 을 가진다. 하지만 다른 python file 에서 해당 module 을 import 해 와 실행하게 된다면 name 은 해당 module 이지만 main 은 import 해 온 제 2의 파일의 name 을 갖게 된다. 그렇기 때문에 위의 조건문은 성립하지 않고, 결국 name 또한 프린트되지 않음을 알 수 있다.

module.py 와 main.py 의 두 파일을 예를 들어보자.

📁 module.py

def say_hi():
	print('Hi!)
print(__name__)

📁 main.py

import module

module.say_hi()

위와 같이 코드를 완성 후 module.py 를 실행시켜보면 아래와 같은 결과가 나온다.

__main__

즉, name 이 main 과 일치함을 알 수 있고, 이는 앞서 말했듯이 say_hi() 함수가 만들어진 해당 파일에서 실행시킨 것이기에 name 과 main 이 같음을 알 수 있다. 이 때, main.py 를 실행시켜보면 module 의 name 이 바로 print 된 것이 확인된다.

module
Hi!

반면에, module.py 에 아래와 같은 조건을 걸었다고 해보자.

📁 module.py

def say_hi():
	print('Hi!)

if __name__ == "__main__"
	print(__name__)

그렇다면 main.py 를 실행시켰을 경우 다음과 같은 결과를 얻게 된다.

Hi!

즉, name 과 main 이 같지 않았기에 module.py 의 name 은 print 되지 않은 것이다. 따라서 우리는 이 때의 main 은 현재 함수가 실행된 main.py 의 name 과 일치할 뿐 module 의 name 과 동일하지 않아 if 문의 조건이 성립되지 않았음을 알 수 있다.


5. VS code vs Pycharm

그동안은 VS Code 를 써왔는데 이번에 새로 강의를 들으며 Pycharm 이라는 프로그램을 쓰게 된 와중에 둘의 차이가 궁금해져 살짝 알아보았다.

  • VS Code 는 generally 호환이 좋아 다양한 언어들을 실행시키기에 적합하다. 또한 최소한의 메모리를 사용하여 "가볍다" 는 장점이 있는 대신 debugging 을 하기에는 친절하지 않다고 한다.

  • Pycharm 은 특히 python 에 특화되어 debugging 또한 용이한 반면에 다양한 packages 가 많아 "무겁다" 고 한다.

0개의 댓글