Programming/Python

[Python 3.7] 파이썬 클래스(class)란? (클래스 생성/호출, 인스턴스.메소드 호출, 속성, 인스턴스 속성 vs 클래스 속성, 클래스 비공개 속성)

Nirsa 2020. 2. 6. 16:09
반응형

 

  • 파이썬 클래스(class)란?

클래스는 객체를 표현하기 위한 문법으로 체크박스, 스크롤바 같은 특정한 개념이나 모양을 존재하는것을 객체(object)라고 부릅니다. 이렇게 객체를 사용한 프로그래밍 언어를 객체 지향(object oriented) 언어라고 부르며 평소에 자주 사용되는 list, dict 등도 모두 각자의 용도에 맞게 만들어진 클래스 입니다.

클래스에는 크게 속성과 메소드 두가지로 구분되는데, 당장은 속성의 경우 매개변수를 받고 사용하기 위한 값을 정의하며 메드는 만들어진 속성들을 이용해 어떤 행위를 하는 실행 코드라고 생각하셔도 됩니다.

예시 들자면 게임의 클래스(직업)를 생각하면 되는데, 각각의 클래스(전사, 마법사, 궁수 등)가 있고 그 안의 속성(힘, 민첩, 지력, 운, 물리공격력, 마법공격력)이 있으며 각각의 메드(찌르기, 파이어볼, 활쏘기 등)가 있다고 생각하셔도 됩니다.

 

  • 클래스,인스턴스 생성과 메소드 호출

아래 코드는 간단히 Hello, World를 출력하는 클래스 입니다. 클래스의 문법은 class 클래스명: 으로 시작하여 안에 함수들이 들어가게 되는데, 클래스를 호출하기 위해선 아래의 a = Hello() 와 같이 인스턴스명 = 클래스명을 입력하여 인스턴스를 생성해주어야 합니다.

이후 생성된 인스턴스.메드() 를 입력하여 Hello 클래스 안에 들어가있는 greeting 메드를 실행 시킵니다.

# 클래스 생성
class Hello:

# 메소드 생성
    def greeting(self):
        print('Hello, World!')

# 인스턴스 생성
a = Hello()

# 메소드 호출
a.greeting()

위에서는 클래스를 만들고, 인스턴스를 생성했으며, 인스턴스.메드로 직접 Hello, World!를 호출 하였습니다.

 

  • 속성

아래 코드는 위에서 했던거에 속성을 추가 하였습니다. __init__ 메드는 introduce = Member('nirsa', 80, '인천 광역시')처럼 인스턴스를 생성할 때 호출되는 특별한 메드 입니다. 인스턴스를 초기화하고 순서에 맞춰 각 인수를 self.속성값 으로 할당 합니다.

# 클래스 선언
class Member:

    # 속성 생성
    def __init__(self, name, age, address):
        self.name = name
        self.age = age
        self.address = address

    # 메소드 생성
    def info(self):
        print('저의 이름은 {0}이고, 나이는 {1}, 사는곳은 {2} 입니다'.format(self.name, self.age, self.address))

# Member의 introduce 인스턴스 생성
introduce = Member('nirsa', 80, '인천 광역시')

# introduce 인스턴스의 info 메소드 호출
introduce.info()

 

  • 인스턴스 속성 vs 클래스 속성

이렇게 사용된 __init__ 이나 각각의 메드에서 self 사용한 속성을 인스턴스 속성이라고 합니다. 인스턴스 속성은 인스턴스별로 각자 다른 값은 가지게 되며, 아래 예시를 보시면 info 메드와 info2의 메드가 서로 다른 인스턴스 속성을 가지고 있습니다. 인스턴스 속성의 특징은 self.속성을 사용합니다

* self는 인스턴스 자기 자신을 가르 킵니다. 즉, 자기 자신만의 인스턴스 속성을 만들고 호출 하는것이며 self 의미를 함께 생각 하는것이 이해하기 수월할 수 있습니다.

class Member:
    value = 10

    def info(self, name, age, address):
        self.name = name
        self.age = age
        self.address = address
        print('저의 이름은 {0}이고, 나이는 {1}, 사는곳은 {2} 입니다'.format(self.name, self.age, self.address))
        print('클래스 인스턴스 {}'.format(Member.value))

    def info2(self, name, age, address):
        self.name = name
        self.age = age
        self.address = address
        print('저의 이름은 {0}이고, 나이는 {1}, 사는곳은 {2} 입니다'.format(self.name, self.age, self.address))
        print('클래스 인스턴스 {}'.format(Member.value))

introduce = Member()

introduce.info('nirsa', 80, '인천 광역시')
introduce.info2('alpha', 68, '서울 특별시')

결과값 : 저의 이름은 nirsa이고, 나이는 80, 사는곳은 인천 광역시 입니다
결과값 : 저의 이름은 alpha이고, 나이는 68, 사는곳은 서울 특별시 입니다

 

아래는 클래스 속성을 빈 리스트로 추가 했습니다. 클래스 속성은 모든 인스턴스에서 공유할 수 있으며 값을 공유 하며 각각의 인스턴스에서 클래스 속성을 공유 합니다. (아래 코드는 info, info2를 호출할 때 클래스 속성의 빈 리스트에 info age의 값을, info2 age의 값을 리스트에 추가 하였습니다.)

인스턴스 속성은 self.속성을 썻다면, 클래스 속성은 클래스명.속성 을 사용 합니다.

class Member:
    value = []

    def info(self, name, age, address):
        self.name = name
        self.age = age
        self.address = address
        print('저의 이름은 {0}이고, 나이는 {1}, 사는곳은 {2} 입니다'.format(self.name, self.age, self.address))

        Member.value.append(age)
        print('클래스 속성 {}'.format(Member.value))

    def info2(self, name, age, address):
        self.name = name
        self.age = age
        self.address = address
        print('저의 이름은 {0}이고, 나이는 {1}, 사는곳은 {2} 입니다'.format(self.name, self.age, self.address))

        Member.value.append(age)
        print('클래스 속성 {}'.format(Member.value))

introduce = Member()

introduce.info('nirsa', 80, '인천 광역시')
introduce.info2('alpha', 68, '서울 특별시')

결과값 : 저의 이름은 nirsa이고, 나이는 80, 사는곳은 인천 광역시 입니다
결과값 : 클래스 인스턴스 [80]
결과값 : 저의 이름은 alpha이고, 나이는 68, 사는곳은 서울 특별시 입니다
결과값 : 클래스 인스턴스 [80, 68]

 

 

  • 비공개 속성

위에서 설명한 클래스는 클래스 밖에서 호출할 수 있었습니다. 비공개 속성은 중요한 값으로 함부로 변경을 시도해서는 안될 때 사용되어 클래스의 메드 안에서만 변경할 수 있습니다.

 기본 속성은 self.속성값 이였다면 비공개 속성은 self.__속성값과 같이 앞에 __ 로 시작하면 됩니다.

아래 코드는 nirsa 인스턴스를 생성하며 Back_book 클래스에 10만원의 금액이 있음을 알리고, nirsa.deposit(50000)을 사용하여 기존의 10만원에 5만원을 더합니다. 잘 보시면 deposit 메드 안에서 계산하는 과정이 일어 납니다.

class Back_book:
    def __init__(self, money):
        self.__money = money
        
    def deposit(self, plus):
        self.__money += plus
        print('입금 후 총 통장 금액은 {0}원 입니다.'.format(self.__money))
        
nirsa = Back_book(100000)
nirsa.deposit(50000)

결과값 : 입금 후 총 통장 금액은 150000원 입니다.

 

글을 작성할 때 비공개 속성은 클래스의 메드 안에서만 변경이 가능하다고 했습니다. 아래 예시들은 비공개 속성을 외부에서 변경을 시도했을때와 비공개 속성이 아닌것을 외부에서 변경을 시도할 때 정상적으로 출력 되는것을 알 수 있습니다.

## 비공개 속성을 외부에서 변경 시도 시 에러 발생
class Back_book:
    def __init__(self, money):
        self.__money = money
        
    def deposit(self, plus):
        print('입금 후 총 통장 금액은 {0}원 입니다.'.format(self.__money))
        
nirsa = Back_book(100000)
nirsa.money += 50000
nirsa.deposit(0)

결과값 : AttributeError: 'Back_book' object has no attribute '__money' 에러 발생


## 비공개 속성을 안했을 때 외부에서 변경 시도 시 정상적으로 변경 됨
class Back_book:
    def __init__(self, money):
        self.money = money
        
    def deposit(self, plus):
        print('입금 후 총 통장 금액은 {0}원 입니다.'.format(self.money))
        
nirsa = Back_book(100000)
nirsa.money += 50000
nirsa.deposit(0)

결과값 : 입금 후 총 통장 금액은 150000원 입니다.

 

마지막으로 클래스 속성도 앞자리에 __를 입력하여 비공개 클래스를 사용할 수 있습니다.

반응형