When will you grow up?

클래스 변수 & 인스턴스 변수([Class,Instance] variable)_02 본문

02. Study/Python

클래스 변수 & 인스턴스 변수([Class,Instance] variable)_02

미카이 2022. 3. 21. 14:08

저번 포스팅에서 Why? 클래스를 사용할 지에 대한 이야기를 간략하게 해봤다.

이번에는 클래스 변수 및 인스턴스 변수가 어떻게 다른지에 대한 이야기를 해보겠다.

 

 

일반적으로 우리가 클래스를 만들게 된다면 object를 상속받게 되어있다.

class Car(object):

    #to do..

하지만 object를 생략하고 만들어도 기본적으로 모든 클래스는 object를 상속받게 되어있다.

class Car():

    # to do..

 

 

그럼 이제 자동차 클래스를 만들어보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class Car(object): # 모든 클래스는 object를 상속받는다.
    ""
    # 파이써닉 규칙 -> 클래스 내용을 적으세요
    Car class
    Author: Mekai
    Data: 2021.03.21
    """
 
    # 클래스 변수(모든 인스턴스가 공유)
    car_count = 0
 
    def __init__(self, company, details):
        self._company = company
        self._details = details
        self.car_count = 10
        Car.car_count += 1
 
    def __str__(self):
        return 'str : {} - {}'.format(self._company, self._details)
 
    def __repr__(self):
        return 'repr: {} - {}'.format(self._company, self._details)
 
    def detail_info(self):
        print('Current ID : {}'.format(id(self)))
        print('Car Detail Info : {} {}'.format(self._company, self._details.get('price')))
 
    def __del__(self):
        print('호출?')
        Car.car_count -= 1
 
car1 = Car('Ferrari', {'color''White''horsepower'400'price'8000})
car2 = Car('Bmw', {'color''Black''horsepower'270'price'5000})
car3 = Car('Audi', {'color''Silver''horsepower'300'price'6000})
cs

위와 같이 클래스를 만들고 3개의 객체(car1, car2, car3)를 만들어보자.

 

Car() 클래스를 보면 다음과 같은 의문이 들 수 있다.

- self 는 무엇을 의미하지 ?

- why 클래스 안에 변수에 self를 붙이는 변수가 있고 아닌 변수들이 있는데 무엇을 의미할까?

간략하게 self의 의미는 인스턴스(instance) 메소드라는 의미인데

car1 = Car('Ferrari', {'color''White''horsepower'400'price'8000})  

이렇게 인스턴스를 만들고 할당되어있는 고유의 인스턴스 메소드라는 의미로 사용되며, 첫번째 매개변수로 넘어오는 것이 약속이다.

무슨말이냐 ?

1
2
3
print(id(car1))
print(id(car2))
print(id(car3))
cs

객체 할당 후 각 고유의 주소(id 메소드 활용)를 확인하면 각 각 다른 주소를 가지고 있는 것을 확인할 수 있다.

self는 각 고유의 값들을 가지고 있기에 인스턴스 고유값을 저장하기 위한 예약어이다(즉, 인스턴스 변수가 될 수 있다).

1
2
3
4
5
6
7
8
9
10
print(car1._company == car2._company) # False (값을 비교) -> 만약 둘 다 Bmw면 True다
print(car1 is car2) # False -> 아이디가 다르기때문 (인스턴스 자체 비교)
 
# dir & __dict__ 확인
print(dir(car1)) # 모든 클래스는 object를 상속받는데 object를 타고올라가면 메소드를 구성되어있는걸 모두 다 보여준다
print(dir(car2)) # 보면 _company, _details도 보여서 list 형태로 다 보여준다 
 
# 그래서 나는 부모꺼말고 내꺼만 보고싶어 내 namespace만 보고싶다
print(car1.__dict__)
print(car2.__dict__)
cs

 

또한, 클래스 작성시

    """ # 파이써닉 규칙
    Car class
    Author: Taehyung
    Data: 2021.03.14
    """

위와 같이 클래스 설명을 써서 만들었는데 정보를 볼 수 있다.(docstring)

1
print(Car.__doc__) # 그 위에 클래스 작성에 달아놓은 """"""  작성 내용이 출력되고 아주 유용하게 사용된다.
cs

 

반면에 self가 붙어 있지 않다면 인스턴스가 아니라 클래스 변수가 된다.

예를들어 동일한 클래스(Car)로 인스턴스를 만들었다면 이 인스턴스끼리 클래스 변수는 모든 인스턴스가 공유가 된다.

Car.car_count += 1 를 넣어준다면 저 실행 값은 car_count가 3번 호출되었기에 값이 3이 된다.

1
2
3
4
5
6
7
8
# 공유 확인
print(Car.car_count)
print(car1.car_count)
print(car2.car_count)
print(car1.__dict__) # 클래스 내부에 정의된 인스턴스만 값만나온다
print(car2.__dict__) 
print(dir(car1)) # 모든 정의된 값이 나온다 -> 클래스 변수로 car_count 값이 나온다
# 약간 느낌이 .. 인스턴스 변수를 만들때 _ 를 붙이는 습관이.. 클래스 내부에서 _ 안붙이면 클래스 변수로 모두가 공유하는 
cs
1
2
3
4
5
6
7
8
9
10
# 접근
# 아래처럼 둘 다 접근이 가능하다..
print(car1.car_count) # 3
print(Car.car_count) # 3
 
 
del car2 # 소멸자 호출
# 삭제 확인
print(car1.car_count) # 2
print(Car.car_count)  # 2
cs

 

마지막으로 네임스페이스를 알아보자.

네임스페이스(namespace)란 프로그래밍 언어에서 특정한 객체(Object)를 이름(Name)에 따라 구분할 수 있는 의미를 가지고 있으며, 우리가 코딩하는 모든 파이썬은 객체로 구성되며 이들 각각은 특정 이름과 매핑 관계를 갖게 되는데 이를 네임스페이스라고 표현한다.

그래서 동일한 클래스로 객체를 만들었어도 다른 공간에 있는 변수가 될 수 있다.

인스턴스 네임스페이스에 없다면 상위에서 검색하는데

즉, 동일한 이름으로 변수 생성 가능 (인스턴스 검색 후 -> 상위(클래스 변수, 부모클래스 변수))

# 인스턴스 변수는 인스턴스 변수로, 클래스 변수는 캘래스 변수로 접근해야 한다.

1
2
print(car1.car_count) # 10
print(Car.car_count)  # 2
cs

 

아주 간략하게 정리하자면 self에 따라 인스턴스 변수가 될 수 있고, self가 없다면 클래스 변수가 될 수 있는데 클래스 변수는 상위 객체(object)에서 관리한다.

 

 

 

우리를 위한 프로그래밍 : 파이썬 중급 를 기반으로 정리하였으며,

기본적인 내용보다는 실질적으로 Why? 라는 의문이 가질 법한 내용 위주로 정리하였습니다.

 

Comments