본문 바로가기

Python_programming/초중급편

파이썬 클래스 사용하기: 인스턴스, self

이번 시간에는 파이썬에서 클래스 사용하는 법에 대해서 다뤄 보겠습니다.

 

버튼, 체크 박스처럼 특정한 개념이나 모양으로 존재하는 것을 객체(object)라고 부릅니다. 그리고 프로그래밍으로 객체를 만들 때 사용하는 것클래스입니다. 

 

파이썬에서 클래스는  

 

class 클래스 이름:

    def 메서드(self):

        코드 

 

이렇게 선언합니다. 

 

선언한 클래스를 사용하려면 인스턴스화 해줘야합니다. 위처럼 변수에 할당하는 것이 인스턴스를 생성하는 것입니다. 

인스턴스 뒤에 .(점)을 붙 이고 메서드를 호출하면 클래스 안에 정의된 함수(=속성이라고 부르겠습니다)를 사용하게 됩니다.

이를 메서드라고 부르고 인스턴스를 통해 호출하는 메서드는 인스턴스 메서드라고 부릅니다. 

 

int, list, dict 등도 사실 클래스입니다. 우리는 이미 클래스로 인스턴스를 만들어서 메서드를 계속 사용했습니다. 

type(객체) 를 실행하면 어떤 클래스인지 확인할 수 있습니다.

 

클래스는 객체를 표현하는 문법인데, 클래스로 인스턴스를 만든다?
사실 인스턴스와 객체는 같은 것을 뜻합니다. 보통 객체만 지칭할 때는 그냥 객체라고 부릅니다. 하지만 클래스와 연관 지어 말할 때인스턴스라고 부릅니다. 리스트 변수 a,b가 있으면 a,b는 객체입니다. 그리고 a와 b는 list 클래스의 인스턴스입니다. 

 

메서드(hello) 안에서 메서드(greeting)를 호출할 때 다음처럼 self.메서드() 형식으로 호출해야 합니다. self 없이 메서드 이름만 사용하면 클래스 바깥쪽에 있는 함수를 호출한다는 뜻이 됩니다.

 

현재 인스턴스가 특정 클래스의 인스턴스인지 확인할 때는 isinstance 함수를 사용합니다. 특정 클래스의 인스턴스가 맞으면 True, 아니면 False를 반환합니다.

 

isinstance 는 주로 객체의 자료형을 판단할 때 사용합니다. 예를 들어 팩토리얼 함수는 1부터 n까지 양의 정수를 차례대로 곱해야 하는데, 실수와 음의 정수는 계산할 수 없습니다. 이런 경우게 isintance를 사용하여 숫자(객체)가 정수일 때 계산하도록 만들 수 있습니다.

 

** 지금부터 클래스에서 속성 만들고 사용하는 것에 대한 설명입니다 **

 

속성(attribute)을 만들 때는 __init__ 메서드 안에서 self.속성에 값을 할당합니다.

 

이 때, self.속성으로 만들어지는 것은 인스턴스 속성이라는 점을 꼭 기억하세요. 

다음 챕터에서 클래스 속성을 설명할 건데 헷갈릴 수 있습니다! self.속성은 인스턴스 속성! 3번 복명복창!

 

 

속성을 만들 때는 init 메서드 안에서 self.속성에 값을 할당합니다.

__ init __ 메서드는 james = Person()처럼 클래스에 ()(괄호)를 붙여서 인스턴스를 만들 때 호출되는 특별한 메서드입니다. 즉, __ init __ 이라는 이름 그대로 인스턴스(객체)를 초기화합니다. 특히 이렇게 앞뒤로 __(밑줄두개) 가 붙은 메서드는 파이썬이 자동으로 호출해주는 메서드인데 이를 스폐셜 메서드(special method) 또는 매직 메서드(magic method)라고 부릅니다. 

 

__ init __ 를 보면 self 다음에 name, age, address를 지정했습니다. 그리고 메서드 안에서는 self.name = name 처럼 매개변수를 그대로 self에 넣어서 속성으로 만들었습니다. 이 때 속성도 인스턴스 속성!

 

위 그림처럼 Person 괄호 안에 넣은 값이 __init__ 메서드에서 self 뒤에 있는 매개 변수가 차례대로 들어갑니다. 

이 때 maria 인스턴스 속성들이 만들어진 것을 계속 상기해주세요!

 

클래스 안에서 속성에 접근할 때 self.속성 형식이었습니다. 클래스 바깥에서 속성에 접근할 때 인스턴스.속성 형식으로 접근합니다. (어떻게 다른지 위의 코드로 다시 한 번 보고 오세요!)

 

다음과 같이 maria.name, maria.age, maria.address의 값을 출력해보면 Person으로 인스턴스를 만들 때 넣었던 값이 출력됩니다. 이렇게 인스턴스를 통해 접근하는 속성을 인스턴스 속성이라 부릅니다.

 

self 의 의미 

self는 인스턴스 자기 자신을 의미합니다. 우리는 인스턴스가 생성될 때 self.hello = '안녕하세요.'처럼 자기 자신에 속성을 추가했습니다. 여기서 __init__의 매개변수 self에 들어가는 값은 Person()이라 할 수 있습니다. 그리고 self가 완성된 뒤 james에 할당됩니다. 이후 메서드를 호출하면 현재 인스턴스가 자동으로 매개변수 self에 들어옵니다. 그래서 greeting 메서드에서 print(self.hello)처럼 속성을 출력할 수 있었던 것입니다.

 

클래스의 위치 인수, 키워드 인수 

클래스로 인스턴스를 만들 때 위치 인수와 키워드 인수를 사용할 수 있습니다. 규칙은 함수와 같습니다. 위치 인수와 리스트 언패킹을 사용하려면 다음과 같이 *args를 사용하면 됩니다. 이때 매개변수에서 값을 가져오려면 args[0]처럼 사용해야 합니다.

 

키워드 인수와 딕셔너리 언패킹을 사용하려면 다음과 같이 **kwargs를 사용하면 됩니다. 이때 매개변수에서 값을 가져오려면 kwargs['name']처럼 사용해야 합니다.

 

인스턴스를 생성한 뒤에 속성 추가하기, 특정 속성만 허용하기

지금까지 클래스의 인스턴스 속성은 __init__ 메서드에서 추가한 뒤 사용했습니다. 하지만 클래스로 인스턴스를 만든 뒤에도 인스턴스.속성 = 값 형식으로 속성을 계속 추가할 수 있습니다. 다음 Person 클래스는 빈 클래스이지만 인스턴스를 만든 뒤 name 속성을 추가합니다.

 

이렇게 추가한 속성은 해당 인스턴스에만 생성됩니다. 따라서 클래스로 다른 인스턴스를 만들었을 때는 추가한 속성이 생성되지 않습니다.

 

인스턴스는 생성한 뒤에 속성을 추가할 수 있으므로 __init__ 메서드가 아닌 다른 메서드에서도 속성을 추가할 수 있습니다. 단, 이때는 메서드를 호출해야 속성이 생성됩니다.

 

인스턴스는 자유롭게 속성을 추가할 수 있지만 특정 속성만 허용하고 다른 속성은 제한하고 싶을 수도 있습니다. 이때는 클래스에서 __slots__에 허용할 속성 이름을 리스트로 넣어주면 됩니다. 특히 속성 이름은 반드시 문자열로 지정해줍니다.

 

비공개 속성 사용하기

 

이번에는 클래스 바깥에서는 접근할 수 없고 클래스 안에서만 사용할 수 있는 비공개 속성(private attribute)을 사용해보겠습니다.

비공개 속성은 __속성과 같이 이름이 __(밑줄 두 개)로 시작해야 합니다. 단, __속성__처럼 밑줄 두 개가 양 옆에 왔을 때는 비공개 속성이 아니므로 주의해야 합니다.

 

실행을 해보면 에러가 발생합니다. self.__wallet처럼 앞에 밑줄 두 개를 붙여서 비공개 속성으로 만들었으므로 클래스 바깥에서 maria.__wallet으로는 접근할 수 없습니다. 

 

비공개 속성은 클래스 안의 메서드에서만 접근할 수 있습니다. 다음과 같이 돈을 내는 pay 메서드를 만들어봅니다.

 

self.__wallet 을 보면 비공개 속성으로 만듬을 확인할 수 있었고 pay 메서드 안에서 접근하는 것을 확인할 수 있습니다. 

maria 인스턴스에서도 pay 메서드를 통해 __wallet 속성에 접근하는 것을 코드에서 확인할 수 있습니다. 

 

보통은 위처럼 쓰기도 합니다. 이처럼 비공개 속성클래스 바깥으로 드러내고 싶지 않은 값에 사용합니다. 즉, 중요한 값인데 바깥에서 함부로 바꾸면 안될 때 비공개 속성을 주로 사용합니다. 비공개 속성을 바꾸는 경우는 클래스의 메서드로 한정합니다.

 

클래스 바깥에서 접근할 수 있는 속성공개 속성(public attribute)이라 부르고, 클래스 안에서만 접근할 수 있는 속성비공개 속성(private attribute)이라 부릅니다.

 

비공개 메서드 사용하기

 

속성뿐만 아니라 메서드도 이름이 __(밑줄 두 개)로 시작하면 클래스 안에서만 호출할 수 있는 비공개 메서드가 됩니다.

위 예시에서 .hello 메서드를 통해 비공개 메서드를 호출할 수 있지만 클래스 밖에서 바로 비공개 메서드를 호출하면 속성을 갖고 있지 않다고 에러가 발생하는 것을 확인할 수 있습니다!

 

비공개 메서드도 메서드를 클래스 바깥으로 드러내고 싶지 않을 때 사용합니다. 보통 내부에서만 호출되어야 하는 메서드를 비공개 메서드로 만듭니다. 예를 들어 게임 캐릭터가 마나를 소비해서 스킬을 쓴다고 치면 마나 소비량을 계산해서 차감하는 메서드는 비공개 메서드로 만들고, 스킬을 쓰는 메서드는 공개 메서드로 만듭니다. 만약 마나를 차감하는 메서드가 공개되어 있다면 마음대로 마나를 차감시킬 수 있으므로 잘못된 클래스 설계가 됩니다.

 

위에서 다룬 클래스에 대한 내용은 길벗 출판사의 '파이썬 코딩도장'을 참고했습니다. 워낙 설명이 잘 나와있어서 중간중간 제가 보충해서 얘기한 거 이외에는 책에 내용을 충실히 정리하였습니다. 개인적으로 파이썬 관련 초중급서로 이 책을 추천합니다. 800p에 달하는 책이지만 파이썬을 쓰는 사람이라면 다 알아야하는 내용들만 있어서 버릴 게 하나도 없습니다. 이 책은 웹에서 검색해서도 볼 수 있지만 이왕이면 소장하시길 추천합니다. (저도 소장하고 있어요 ㅎ) 이 책은 두고두고 헷갈리거나 생각 안나는 부분이 있을 때 계속 봐야되기 때문입니다!

 

그러면 다음에도 유익한 내용으로 포스팅 하겠습니다 :)