Class 에 대해 알아보다 인터넷에서 조금 이상한 코드를 발견하였다.
class Car:
color = "" #인스턴스 변수
speed = 0 # 인스턴스 변수
count = 0 # 클래스 변수
def __init__(self):
self.speed = 0
Car.count += 1
# 변수 선언
myCar1, myCar2 = None, None
# 메인 코드 부분
myCar1 = Car()
myCar1.speed = 30
print("%dkm, %d"%(myCar1.speed, Car.count))
myCar2 = Car()
myCar2.speed = 60
print("%dkm, %d"%(myCar2.speed, myCar2.count))
# 결과
# 30km, 1
# 60km, 2
자 이 코드로 Class 변수에 대해 알아보려 한다. 우선 위의 주석에 적힌 #인스턴스 변수 라는 것은 사실 모두 잘못된 것이다. Instance 변수는 각각의 instance 마다 독립인 변수이다. 따라서 저렇게 선언을 하면 안된다.
우선 위의 코드에서 무슨 일이 일어나고 있는 것인지 살펴보자.
class Car:
color = "" #인스턴스 변수
speed = 0 # 인스턴스 변수
count = 0 # 클래스 변수
def __init__(self):
self.speed = 0
Car.count += 1
자 여기에서 class가 선언되었다.
자 그러면 다음과 같이 Car라는 class namespace에 dict형태로 위의 것들이 들어가게 된다.
다음으로
# 변수 선언
# myCar1, myCar2 = None, None
이 부분은 사실 필요가 없다. 다음으로 넘어가보도록 하겠다.
이제
myCar1 = Car()
myCar1.speed = 30
print("%dkm, %d"%(myCar1.speed, Car.count))
에서
다음과 같이 동작해서 print문을 하게 되면, Car namespace의 count와, myCar1의 speed를 출력하게 되어서 30km, 1이 출력되게 된다. 위의 동작을 좀더 알아보고 싶다면, __dict__ 메소드를 활용해 보기를 추천한다.
다음으로
myCar2 = Car()
myCar2.speed = 60
print("%dkm, %d"%(myCar2.speed, myCar2.count))
에서는 무슨 일이 일어나는 것일까?
다음과 같은 일이 일어난다.
speed를 60으로 만드는 과정까지는 동일한데 여기서 다른점은 myCar2.count를 조회하게 되면, myCar2의 instance namespace에 count가 없기에 Car class namespace의 count를 가져와서 올바르게 출력이 가능한 것이다.
더불어서 위의 코드 대로라면, Car class의 __init__ 메소드에 self.speed의 정의가 없어도 코드는 정상작동한다.
궁금한 사람들은 아래의 코드를 돌려보기를 바란다.
class Car:
color = "" #인스턴스 변수
speed = 0 # 인스턴스 변수
count = 0 # 클래스 변수
def printMessage():
print("시험 출력")
def __init__(self):
#self.speed = 0
Car.count += 1
# 메인 코드 부분
myCar1 = Car()
# print(myCar1.__dict__) -> 주석해제 해보기
myCar1.speed = 30
# print(myCar1.__dict__) -> 주석해제 해보기
print("%dkm, %d"%(myCar1.speed, Car.count))
myCar2 = Car()
myCar2.speed = 60
print("%dkm, %d"%(myCar2.speed, myCar2.count))
이렇게 nested 하게 코드를 만들 수도 있지만 이렇게 코드를 만들면 이해하기가 어렵다. 사람들이 편하게 알아보기 위해서 instance variable과 class variable을 올바르게 선언 해서 필요에 따라 잘 활용해야 할 것 같다.
'공부 > Python' 카테고리의 다른 글
[Python] mutable 과 immutable (Python의 포인터, 변수에 관한 이야기) (0) | 2022.05.09 |
---|