티스토리 뷰

Python

[Python] 클래스 (2)

SeYuNi 2024. 2. 8. 22:26

 속성에는 클래스 속성과 인스턴스 속성 두 가지 종류가 있다. __init__ 메서드에서 만들었던 속성은 인스턴스 속성이다.

 

클래스 속성 사용하기

class 클래스이름:
    속성 = 값
class Person:
    bag = []
 
    def put_bag(self, stuff):
        self.bag.append(stuff)
 
james = Person()
james.put_bag('책')
 
maria = Person()
maria.put_bag('열쇠')
 
print(james.bag)
print(maria.bag)

실행결과

['책', '열쇠']
['책', '열쇠']

james와 maria 인스턴스를 만들고 각자 put_bag 메서드로 물건을 넣었는데, james.bag과 maria.bag을 출력해보면 넣었던 물건이 합쳐져서 나온다. 클래스 속성은 클래스에 속해 있으며 모든 인스턴스에서 공유한다.

클래스 속성

put_bag 메서드에서 클래스 속성 bag에 접근할 때 self를 사용했다. 사실 self는 현재 인스턴스를 뜻하므로 클래스 속성을 지칭하기에는 조금 모호하다.

class Person:
    bag = []
 
    def put_bag(self, stuff):
        self.bag.append(stuff)

그래서 클래스 속성에 접근할 때는 다음과 같이 클래스 이름으로 접근하면 좀 더 코드가 명확해진다.

  • 클래스.속성
class Person:
    bag = []
 
    def put_bag(self, stuff):
        Person.bag.append(stuff)    # 클래스 이름으로 클래스 속성에 접근

Person.bag이라고 하니 클래스 Person에 속한 bag 속성이라는 것을 바로 알 수 있다. 마찬가지로 클래스 바깥에서도 다음과 같이 클래스 이름으로 클래스 속성에 접근하면 된다.

print(Person.bag)

 

클래스 속성을 찾는 과정

 

인스턴스 속성 사용하기

bag을 인스턴스 속성으로 만들면  가방을 여러 사람이 공유하지 않을 수 있다.

class Person:
    def __init__(self):
        self.bag = []
 
    def put_bag(self, stuff):
        self.bag.append(stuff)
 
james = Person()
james.put_bag('책')
 
maria = Person()
maria.put_bag('열쇠')
 
print(james.bag)
print(maria.bag)
['책']
['열쇠']

james.bag과 maria.bag을 출력해보면 각자 넣은 물건만 출력된다. 즉, 인스턴스 속성은 인스턴스별로 독립되어 있으며 서로 영향을 주지 않는다.

 

 

  • 클래스 속성: 모든 인스턴스가 공유. 인스턴스 전체가 사용해야 하는 값을 저장할 때 사용
  • 인스턴스 속성: 인스턴스별로 독립되어 있음. 각 인스턴스가 값을 따로 저장해야 할 때 사용

 

비공개 클래스 속성 사용하기

클래스 속성을 만들 때 __속성과 같이 __(밑줄 두 개)로 시작하면 비공개 속성이 된다. 따라서 클래스 안에서만 접근할 수 있고, 클래스 바깥에서는 접근할 수 없다.

class 클래스이름:
    __속성 = 값    # 비공개 클래스 속성

즉, 클래스에서 공개하고 싶지 않은 속성이 있다면 비공개 클래스를 사용해야 한다.

 

정적 메서드 사용하기

정적 메서드는 다음과 같이 메서드 위에 @staticmethod를 붙인다. 이때 정적 메서드는 매개변수에 self를 지정하지 않는다.

class 클래스이름:
    @staticmethod
    def 메서드(매개변수1, 매개변수2):
        코드

@staticmethod처럼 앞에 @이 붙은 것을 데코레이터라고 하며 메서드(함수)에 추가 기능을 구현할 때 사용한다.

 

간단하게 덧셈과 곱셈을 하는 클래스를 만들어보면,

class Calc:
    @staticmethod
    def add(a, b):
        print(a + b)
 
    @staticmethod
    def mul(a, b):
        print(a * b)
 
Calc.add(10, 20)    # 클래스에서 바로 메서드 호출
Calc.mul(10, 20)    # 클래스에서 바로 메서드 호출

실행결과

30
200

Calc 클래스에서 @staticmethod를 붙여서 add 메서드와 mul 메서드를 만들었다. 정적 메서드를 호출할 때는 다음과 같이 클래스에서 바로 메서드를 호출하면 된다.

  • 클래스.메서드()
Calc.add(10, 20)    # 클래스에서 바로 메서드 호출
Calc.mul(10, 20)    # 클래스에서 바로 메서드 호출

정적 메서드는 self를 받지 않으므로 인스턴스 속성에는 접근할 수 없다. 그래서 보통 정적 메서드는 인스턴스 속성, 인스턴스 메서드가 필요 없을 때 사용한다.

여기서 만든 Calc 클래스에 들어있는 add, mul 메서드는 숫자 두개를 받아서 더하거나 곱할 뿐 인스턴스의 속성은 필요하지 않는다.

 

정적 메서드는 메서드의 실행이 외부 상태에 영향을 끼치지 않는 순수 함수(pure function)를 만들 때 사용한다. 순수 함수는 부수 효과(side effect)가 없고 입력 값이 같으면 언제나 같은 출력 값을 반환한다. 즉, 정적 메서드는 인스턴스의 상태를 변화시키지 않는 메서드를 만들 때 사용한다.

 

클래스 메서드 사용하기

클래스 메서드는 다음과 같이 메서드 위에 @classmethod를 붙인다. 이때 클래스 메서드는 첫 번째 매개변수에 cls를 지정해야 한다.(cls는 class에서 따왔다)

class 클래스이름:
    @classmethod
    def 메서드(cls, 매개변수1, 매개변수2):
        코드

 

사람 클래스 Person을 만들고 인스턴스가 몇 개 만들어졌는지 출력하는 메서드를 만들어보면,

class Person:
    count = 0    # 클래스 속성
 
    def __init__(self):
        Person.count += 1    # 인스턴스가 만들어질 때
                             # 클래스 속성 count에 1을 더함
 
    @classmethod
    def print_count(cls):
        print('{0}명 생성되었습니다.'.format(cls.count))    # cls로 클래스 속성에 접근
 
james = Person()
maria = Person()
 
Person.print_count()    # 2명 생성되었습니다.

실행결과

2명 생성되었습니다.

먼저 인스턴스가 만들어질 때마다 숫자를 세야 하므로 __init__ 메서드에서 클래스 속성 count에 1을 더해준다. 물론 클래스 속성에 접근한다는 것을 명확하게 하기 위해 Person.count와 같이 만들어준다.

class Person:
    count = 0    # 클래스 속성
 
    def __init__(self):
        Person.count += 1    # 인스턴스가 만들어질 때
                             # 클래스 속성 count에 1을 더함

이제 @classmethod를 붙여서 클래스 메서드를 만든다. 클래스 메서드는 첫 번째 매개변수가 cls인데 여기에는 현재 클래스가 들어온다. 따라서 cls.count처럼 cls로 클래스 속성 count에 접근할 수 있다.

    @classmethod
    def print_count(cls):
        print('{0}명 생성되었습니다.'.format(cls.count))    # cls로 클래스 속성에 접근

Person으로 인스턴스를 두 개 만들었으므로 print_count를 호출해보면 '2명 생성되었습니다.'가 출력된다. 물론 print_count는 클래스 메서드이므로 Person.print_count()처럼 클래스로 호출해준다.

james = Person()
maria = Person()
 
Person.print_count()    # 2명 생성되었습니다.

클래스 메서드는 정적 메서드처럼 인스턴스 없이 호출할 수 있다는 점은 같다. 하지만 클래스 메서드는 메서드 안에서 클래스 속성, 클래스 메서드에 접근해야 할 때 사용한다.

특히 cls를 사용하면 메서드 안에서 현재 클래스의 인스턴스를 만들 수도 있다. 즉, cls는 클래스이므로 cls()는 Person()과 같다.

    @classmethod
    def create(cls):
        p = cls()    # cls()로 인스턴스 생성
        return p

 

 

 

 

 

 

 

 

 

 

'Python' 카테고리의 다른 글

[Python] 예외 처리 사용하기  (1) 2024.02.08
[Python] 클래스 (3)  (1) 2024.02.08
[Python] 클래스 (1)  (0) 2024.02.08
[Python] 람다 표현식으로 함수 만들기  (0) 2024.02.08
[Python] 기본 문법 정리 (4)  (0) 2024.02.03
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/07   »
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
글 보관함