본문 바로가기

Programming Language/Python

파이썬_기초단계 알아보기_ep.7 오리눈과 오리눈 집게. 객체&클래스

320x100

 

이번 회차에는 파이썬의 객체와 클래스
인스턴스, 그리고 이에 쓰이는 메서드를 확인해봅니다.
고지가 얼마 남지 않았습니다!!


 

서론

 

출처. 인사이트 뉴스

 

이번 해도 어김없이 겨울이 찾아왔습니다.

지난해 겨울에는 유난히 눈이 많이왔는데요. 

 

이맘때쯤 대한민국을 강타했던 것이 바로 오리로 만든 눈!

즉 오리눈 입니다. 🦆🦆⛄

 

오리눈 집게와 펑펑 내린 눈만 있으면 무한대로 만들 수 있는 것이

이 오리눈이었는데요. 이 집게때문에 아이들이 사는 집앞에는 

귀여운 새끼 오리들이 옹기종기 모여있는 장관이 연출되었습니다.

올해는 어떤 것이 유행이 될지 모르겠는데요.

 

이때, 파이썬에서의 클래스는 오리눈 집게, 객체는 오리눈의 역할과 같습니다.

즉, 변수만 설정할 수 있다면 오리눈을 계속 찍어낼 수 있는데요.

어떻게 할 수 있는지 한번 알아보겠습니다.

객체와 클래스 부분은 어렵습니다.

하 지 만

어떠한 언어를 배우든 중요한건
꺾이지 않는 마음!!!

 


오늘 부분은 용어의 의미 자체를 탐구하는 것보다는 실제 파이썬에서

어떻게 쓰이는지, 어떠한 메서드가 쓰이는지 실천해보는 것이 더욱

중요합니다.

 

때문에 처음보는 용어에 대한 설명은 신속하게 진행하겠습니다.

 

 

객체와 클래스

클래스 선언과 객체 생성

객체란?

속성과 행위로 구성된 대상을 의미해요.

속성은 상태, 특징을 의미합니다.

행위란 일종의 행동, 동작, 기능을 의미합니다.

 

객체는 변수와 함수의 묶음

객체가 무엇인가요?

 

☞ 이렇게 한번 예시를 들어보겠습니다.
객체가 사람이라면, 변수는 그 사람의 키, 몸무게, 이름과 같은 것입니다.
그리고 함수는 걷기나 뛰기처럼 그 사람이 행동하는 것입니다. 

 

클래스 선언

 

사용자가 정한 이 클래스명으로 앞으로 함수나, 다른 것들을

넣어서 사용하겠다는 일종의 시작점입니다.

아래 구조로 사용합니다.

 

class 클래스명():
[변수1] #클래스 변수
[변수2]

....

def 함수1(self, 인자1, 인자2) : #클래스 함수

<코드 블록>

...

def 함수2(self, 인자1, 인자2) :

<코드 블록>

...

 

객체 생성 및 활용

 

자 이제, 이번시간의 전체적인 최종 목적은 특정한 속력으로 움직이고

이리저리 방향을 정할 수 있는 자전거를 만드는 것입니다.

결과값을 어느정도 상상해보고

....

일단 이를 위해서 클래스를 Bicycle로 선언해보겠습니다!

 

class Bicycle(): # 클래스 선언 / 
    pass

 

좋습니다. 아직까지는 특별히 어떠한 행위도 하지 않습니다.

 

룰 넘버원
클래스는 맨 앞의 대문자로만 시작합니다!

 

클래스는 소문자로 시작하지 않습니다.

무조건 대문자로 시작합니다 (어법 때문일까요?)

 

클래스로부터 인스턴스(instance)인 객체를 선언

 

엄밀히 따지면 인스턴스는 객체에 포함됩니다. 

다만 잠시 어떠한 속성을 갖기 위해 제가 만드는 것이죠.

같은 객체이지만, 다른 인스턴스를 가질 수 있어요.

 

위에서 오리눈 집게를 갖고 놀던 때를 가져와봅시다.

오리눈 집게와 오리눈 과의 관계에서 오리눈 집게는 클래스로,

오리눈은 객체로 볼 수 있습니다. 이때, 쑥 튀어나온 오리눈은

오리눈 집게의 인스턴스라고 표현합니다.

 

반복할수록 헷갈리게 되네요🌜 일단 한번 보겠습니다.

 

구조

객체명 = 클래스명()

 

my_bicycle이라는 인스턴스를 선언해보겠습니다.

 

my_bicycle = Bicycle()

my_bicycle
<__main__.Bicycle at 0x297af634b50>

▲이런 인스턴스가 위 메모리(ram)에 저장되었다는 뜻입니다.

 

객체에 속성을 추가하기

구조

 

객체명.변수명 = 속성값

 

속성은 인간이 인간이게끔 하는 것입니다.

행위는 인간이 세상이나 물체, 인간에게 영향을 끼치는 것입니다.

클래스는 인간에게 한 세계를 부여하는 것입니다.

 

객체에 속성을 추가하기

객체명.변수명 = 속성값
my_bicycle.wheel_size = 26
my_bicycle.color = '검정색'

 

속성 가져오기

구조

객체명.변수명

 

print('바퀴 크기 :', my_bicycle.wheel_size)
print('색상 :',my_bicycle.color)
바퀴 크기 : 26
색상 : 검정색

 

함수 추가 (행위)

 

이제 Bicycle의 행동을 의미할 함수를 추가해보겠습니다.

 

class Bicycle():
    
    def move(self, speed):
        print('자전거: 시속 {}km로 전진'.format(speed))
    
    def turn(self, direction):
        print('자전거: {0}회전'.format(direction))
        
    def stop(self):
        print('자전거 ({0},{1}): 정지'.format(self.wheel_size, self.color))

 

객체를 메서드에 호출

구조

객체명.메서드명(인자1, 인자2...)

 

좋습니다. 이제 객체의 속성을 설정하고 메서드도 호출해 봅니다.

바퀴 크기는 26, 색깔은 검정색으로 지정했구요.

속력은 30, 좌회전 하는 것으로 설정했습니다.

 

my_bicycle = Bicycle() # Bicycle 클래스의 인스턴스인 my_bicycle 객체 생성

my_bicycle.wheel_size = 26
my_bicycle.color = "검정색"  # 객체의 속성 설정

my_bicycle.move(30)  # 객체의 메서드 호출
my_bicycle.turn('좌')
my_bicycle.stop()
자전거: 시속 30km로 전진
자전거: 좌회전
자전거 (26,검정색): 정지

 

잘 출력되는 것을 볼 수 있습니다.

다른 인스턴스를 구성해보겠습니다.

무지막지하게 빨리 달리는 bicycle1, bicycle2을 보겠습니다.

 

bicycle1 = Bicycle() # Bicycle 클래스의 인스턴스인 bicycle1 객체 생성

bicycle1.wheel_size = 24  # 객체의 속성 설정
bicycle1.color = 'blue'

bicycle1.move(34)
bicycle1.turn('우')
bicycle1.stop()  # 객체의 메서드 설정

bicycle2 = Bicycle() # Bicycle 클래스의 인스턴스인 bicycle2 객체 생성

bicycle2.wheel_size = 25
bicycle2.color = '레드'

bicycle2.move(100)
bicycle2.turn('뒤')
bicycle2.stop()
자전거: 시속 34km로 전진
자전거: 우회전
자전거 (24,blue): 정지
자전거: 시속 100km로 전진
자전거: 뒤회전
자전거 (25,레드): 정지

 

 

무지 천천히 달리는 bicycle3도 생성해 볼까요?

 

bicycle3 = Bicycle() # Bicycle 클래스의 인스턴스인 bicycle3 객체 생성

bicycle3.wheel_size = 99
bicycle3.color = '레드'

bicycle3.move('1')
bicycle3.turn('좌')
bicycle3.stop()
자전거: 시속 1km로 전진
자전거: 좌회전
자전거 (99,레드): 정지

 

이제 속성을 날리고 깔끔하게 새로 시작하는 함수에 대해 알아보겠습니다.

 

객체 초기화

init 함수

 

__init__을 사용하면 객체를 생성하는 것과 동시에 속성값을 지정할 수 있습니다.

생성될 때 자동으로 실행되기 때문에 속성을 초기화 할 수 있습니다.

※ 언더바를 2개 사용합니다

 

class Bicycle():
    
    def __init__(self,wheel_size,color):
        self.wheel_size = wheel_size
        self.color = color
        
    def move(self, speed):
        print("자전거 : 시속 {0}km로 전진".format(speed))
        
    def turn(self, direction):
        print("자전거 : {0}로 회전".format(direction))
        
    def stop(self):
        print("자전거({0},{1}): 정지".format(self.wheel_size, self.color))

 

자 여기서 self는 쓰이지 않고 무시 후 넘어갑니다.

객체를 설정하면서 인수를 바로 넣을수도 있습니다.

 

구조

객체명 = 클래스명(인자1, 인자2 ...)

 

my_bicycle = Bicycle(26, "black")  # 객체 생성과 동시에 속성값을 지정.

my_bicycle.move(30)  # 객체 메서드 호출
my_bicycle.turn('좌')
my_bicycle.stop()
자전거 : 시속 30km로 전진
자전거 : 좌로 회전
자전거(26,black): 정지

 

처음 인스턴스와 동일하게 잘 나오네요.

 

클래스를 구성하는 요소

클래스에서 사용하는 변수들은 어떤것들이 있을까요?

 

클래스 변수 = 클래스 내에 있지만, 함수밖에서 "변수명 = 데이터" 형식으로
정의되며 모든 객체가 공통 사용 "클래스명.변수명"으로 사용합니다.

인스턴스 변수 = 함수내에서 사용된 변수이며
'self.변수명 = 데이터'형식으로 정의한 변수로서 'self.변수명'으로 접근할 수 있습니다.

 

class Car():
    instance_count = 0 # 클래스 변수 생성 및 초기화
    
    def __init__(self, size, color):
        self.size = size  # 인스턴스 변수 생성 및 초기화
        self.color = color # 인스턴스 변수 생성 및 초기화
        Car.instance_count = Car.instance_count + 1 # 클래스 변수 이용
        print("자동차 객체의 수: {0}".format(Car.instance_count))
        
    def move(self):
        print("자동차 ({0} & {1})가 움직입니다.".format(self.size , self.color))

 

car1 = Car('small','white')
car2 = Car('big', 'black')
car3 = Car('huge', 'red')
car4 = Car('tiny', 'yellow')
자동차 객체의 수: 1
자동차 객체의 수: 2
자동차 객체의 수: 3
자동차 객체의 수: 4

 

클래스명.변수명으로 언제든지 호출할 수 있습니다.

 

print('Car 클래스의 총 인스턴스 개수:{}'.format(Car.instance_count))
Car 클래스의 총 인스턴스 개수:4

 

+모든 객체에서 공통으로 사용합니다.

 

print("Car 클래스의 총 인스턴스 개수:{}".format(car1.instance_count))
print("Car 클래스의 총 인스턴스 개수:{}".format(car2.instance_count))
Car 클래스의 총 인스턴스 개수:4
Car 클래스의 총 인스턴스 개수:4

 

인스턴스 변수는 각 객체에서 별도로 관리됩니다

 

car1.move()
car2.move()
car3.move()
car4.move()
자동차 (small & white)가 움직입니다.
자동차 (big & black)가 움직입니다.
자동차 (huge & red)가 움직입니다.
자동차 (tiny & yellow)가 움직입니다.

 

이름이 같은 클래스 변수와 인스턴스 변수의 경우

 

class Car2():
    count = 0; # 클래스 변수 생성 및 초기화
    
    def __init__(self, size, num):
        self.size = size  # 인스턴스 변수 생성 및 초기화
        self.count = num  # 인스턴스 변수 생성 및 초기화
        Car2.count = Car2.count+1 # 클래스 변수 이용
        print("자동차 객체의 수: Car2.count = {0}".format(Car2.count))
        print("인스턴스 변수 초기화: self.count = {0}".format(self.count))
        
    def move(self):
        print('자동차 ({0} & {1})가 움직입니다.'.format(self.size, self.count))

 

이부분에서도 self는 쓰이지 않고 무시하고 넘어갑니다.

변수 이름은 같지만 별개로 동작합니다.

 

Car1 = Car2("big", 20)
Car1 = Car2("small", 30)
자동차 객체의 수: Car2.count = 1
인스턴스 변수 초기화: self.count = 20
자동차 객체의 수: Car2.count = 2
인스턴스 변수 초기화: self.count = 30

 

클래스에서 사용하는 함수

인스턴스 메서드

각 객체에서 개별적으로 동작하는 함수를 만들고자 할 때 사용하는 함수입니다

 

구조

 

class 클래스명():

def 함수명(self, 인자1, 인자2, ....인자n):

self.변수명1 = 인자1
self.변수명2 = 인자2
self.변수명3 = 데이터

...

<코드블록>

 

다음과 같이 객체를 생성한 후에 호출할 수 있습니다.

 

객체명 = 클래스명()

객체명.메서드명(인자1, 인자2, 인자3, ... 인자n)

 

이번에는 클래스를 선언하고 변수 생성+초기화를 진행합니다.

그리고 초기화 함수도 쓰고, move, 자율주행기능을 언급하는 메서드를

따로 제작해보겠습니다.

 

# Car 클래스 선언
class Car():
    instance_count = 0 # 클래스 변수 생성 및 초기화
    
    # 초기화 함수(인스턴스 메서드)
    def __init__(self, size, color):  
        self.size = size # 인스턴스 변수 생성 및 초기화
        self.color = color # 인스턴스 변수 생성 및 초기화
        Car.instance_count = Car.instance_count+1 # 클래스 변수 이용
        print("자동차 객체의 수:{0}".format(Car.instance_count))
        
    # 인스턴스 메서드
    def move(self, speed):
        self.speed = speed # 인스턴스 변수 생성
        print("자동차({0} & {1})가".format(self.size,self.color), end='')
        print('시속 {0}km로 전진'.format(self.speed))
        
    # 인스턴스 메서드
    def auto_cruise(self):
        self.speed = speed # 인스턴스 변수 생성
        print('자동차({0} & {1}가 '.format(self.size, self.color),end='')
        print('시속 {0} 킬로미터로 전진'.format(self.speed))
        
    #인스턴스 메서드
    def auto_cruise(self):
        print("자율 주행 모드")
        self.move(self.speed)  # move() 함수의 인자로 인스턴스 변수를 입력

 

내용이 꽤 길어졌죠?

아래처럼 호출하겠습니다.

 

car1 = Car('Small', 'Red')
car2 = Car('Big' , 'Green')

car1.move(80)  # 객체(car1)의 move() 메서드 호출
car2.move(100) # 객체(car2)의 move() 메서드 호출

car1.auto_cruise() # 객체(car1)의 auto_cruise() 메서드 호출
car2.auto_cruise() # 객체(car2)의 auto_cruise() 메서드 호출
자동차 객체의 수:1
자동차 객체의 수:2
자동차(Small & Red)가시속 80km로 전진
자동차(Big & Green)가시속 100km로 전진
자율 주행 모드
자동차(Small & Red)가시속 80km로 전진
자율 주행 모드
자동차(Big & Green)가시속 100km로 전진

 

정적 메서드

 

클래스나 클래스의 인스턴트(객체)와는 무관하게

독립적으로 만들고 싶은 함수를 만들고 싶을 때 사용합니다.

 

함수 앞에 @staticmethod 를 선언해서 사용해요

 

class 클래스명():

@staticmethod

def 함수명 (인자1, 인자2, ... , 인자n):

    <코드 블록>
정적 메서드는 보통 객체를 생성하지 않고 클래스명을 이용해 바로 메서드를 호출합니다.

 

구조

클래스명.메서드명(인자1, 인자2, ... , 인자n):

날짜 및 시간 정보 제공, 환율 정보 제공, 단위변환과 같이
객체와 관계없이 독립적으로 동작하는 함수를 만들 때 주로 사용합니다

 

이번에도 Car로 클래스를 선언해보겠습니다.

(조건문 사용)

 

# Car 클래스 선언
class Car():
    
    # def __init__(self, size, color) : → 앞의 코드 활용
    # def move(self, speed): → 앞의 코드 활용
    # def auto_cruise(self): → 앞의 코드 활용
    
    # 정적 메서드
    @staticmethod
    
    def check_type(model_code):
        if(model_code >= 20):
            print('이 자동차는 전기차입니다.')
        elif(10 <= model_code < 20):
            print('이 자동차는 가솔린차입니다.')
        else:
            print('이 자동차는 디젤차입니다.')

 

이때, __init__, move, auto_cruise는 앞전에 저장한 인스턴스가

따로 수정된 점이 없으면 그대로 저장되어 있으므로, 그대로

사용됩니다.

 

@staticmethod 뒤를 주목해주세요.

각 모델 코드별로 무엇이 달라지는지 보이시나요?

 

모델 코드를 마음대로 설정해보겠습니다.

 

Car.check_type(21)
Car.check_type(10)
Car.check_type(1)
이 자동차는 전기차입니다.
이 자동차는 가솔린차입니다.
이 자동차는 디젤차입니다.

 

이번 시간의 마지막으로 클래스 메서드를 보겠습니다.

 

클래스 메서드

클래스 변수를 사용하기 위한 함수입니다

 

함수를 정의할 때 첫번째 인자로 클래스를 넘겨받는 것이 필요하며

이는 cls 를 사용합니다.

이를 이용해 클래스 변수에 접근합니다. 

 

구조

 

class 클래스명():

@classmethod

def 함수명(cls, 인자1, 인자2, ... , 인자n):

    <코드 블록>

클래스 메서드로 객체를 생성하지 않고 바로 호출 가능

클래스명.메서드명(인자1, 인자2, ... , 인자n):

 

함수 앞에 @Classmethod를 지정해야 합니다!

클래스 메서드는 생성된 객체의 갯수를 반환하는 등

클래스 전체에서 관리해야 할 기능이 있을때 주로 사용합니다.

 

직접 예시문을 보겠습니다.

 

# Car 클래스 선언
class Car():
    instance_count = 0 # 클래스 변수

    # 초기화 함수(인스턴스 메서드)
    def __init__(self, size, color):
        self.size =  size  # 인스턴스 변수
        self.color = color # 인스턴스 변수
        Car.instance_count = Car.instance_count+1
        
    # def move(self, speed) : ▶ 앞의 코드 활용
    # def auto_cruise(self) : ▶ 앞의 코드 활용
    # @staticmethod
    # def check_type(mode_code) : ▶ 앞의 코드 활용
    
    # 클래스 메서드
    @classmethod
    def count_instance(cls):
        print('자동차 객체의 개수 :{0}'.format(cls.instance_count))

 

마찬가지로 중복되는 건 앞의 코드를 사용하구요, 

@classmethod와 format을 사용했습니다.

이때 instance_count는 객체가 증가할 때마다 1씩 증가합니다.

클래스 메서드를 호출하면 현재까지 생성된 객체의 개수를 알 수 있습니다.

 

Car.count_instance()  # 객체 생성 전에 클래스 메서드 호출
자동차 객체의 개수 :0

 

자 이제 제가 쓴 인수들을 몇가지 넣어서 클래스 메서드를 

호출해보겠습니다.

 

car1 = Car('Small', 'red')  # 첫 번째 객체 생성
Car.count_instance()  # 클래스 메서드 호출

car2 = Car('Big', 'green')  # 두 번째 객체 생성
Car.count_instance()  # 클래스 메서드 호출
자동차 객체의 개수 :1
자동차 객체의 개수 :2

 

다시 반복하면 어떻게 될까요?

 

car1 = Car('Small', 'red')  # 첫 번째 객체 생성
Car.count_instance()  # 클래스 메서드 호출

car2 = Car('Big', 'green')  # 두 번째 객체 생성
Car.count_instance()  # 클래스 메서드 호출
자동차 객체의 개수 :3
자동차 객체의 개수 :4

 

역시 instance_count가 1씩 증가하게 됩니다.

 

 

이쯤에서 제가 실패한 부분을 밝힙니다.

 

 

 

 

네 맞습니다. 클래스들을 설명하면서 분량조절에 실패했습니다.

예상과 달리 제시해야 되는 부분이 상당히 길어졌습니다.

 

그 래 서 일단은

다음시간에는 객체와 클래스를 사용하는 이유, 이에 대한 더 많은 예시문, 클래스 상속에 대해서

확인해 보겠습니다.

 

다음 단계 배우기 : https://astart.tistory.com/17
728x90