반응형

안녕하세요, 왕초보 코린이를 위한 코딩유치원에 오신 것을 환영합니다.

코딩유치원에서는 파이썬 기초부터 사무자동화, 웹크롤링, 데이터 분석 등의 다양한 패키지까지 초보자도 알기 쉽도록 내용을 정리해 놓았습니다.

업무는 물론 투자에도 도움이 될만한 전자공시시스템(DART) 텔레그램(Telegram) 관련 패키지도 배울 수 있으니 많은 관심 부탁드립니다.

 

 

제가 지금까지 다루었던 프로젝트들은 리스트만으로 충분했으나, 최근 진행한 프로젝트에서는 리스트들끼리 짝을 맞추어서 저장하고, 꺼내어 사용해야 하는 경우가 생기니깐 어떻게 해야할지 잘 모르겠더라구요.

 

그래서 오늘은 길이가 같은 리스트들의 요소들을 차례대로 조합해서 새로운 리스트, 딕셔너리로 만드는 방법에 대해서 알아보고, 그것을 어떻게 다시 참조할 수 있는지 함께 알아보겠습니다.

 

 

1. 리스트 2개를 요소들끼리 묶어주는 법

 

보통 코드를 짜다보면, 요소들을 받아와서 리스트에 차곡차곡 쌓는 경우가 많습니다.

 

그런데 이 리스트들을 요소들끼리 순서대로 묶어주고 싶을 때가 있습니다.

 

 

[사과, 1000원], [딸기, 2000원], ... 이런 식으로 말이죠.

 

이럴 때는 파이썬 내장 라이브러리에 포함되어 있는 zip 함수를 사용합니다.

 

사용법은 간단합니다. 리스트명을 zip( ) 안에 순서대로 넣어주면 됩니다.

 

여기서 꼭 알아두실 점은 zip( )만 사용하면 그냥 리스트의 내용물이 분배된 상태로 zip object 로 저장된다는 것입니다.

 

product_names = ['사과','딸기','배','포도','키위']
product_prices = ['1000원','2000원','3000원','4000원','5000원']

zip_obj = zip(product_names, product_prices)

 

실제로 zip_obj를 print 함수로 출력해보면 <zip object at 0x0000019014B3A3C0>와 같은 형태로 출력됩니다.

 

우리는 이 zip_obj를 리스트로 만들어 줄 수도 있고, 딕셔너리로도 만들어 줄 수 있습니다.

(리스트로 만들 시, 각 요소들이 튜플로 묶여있음)

 

list(zip_obj)
>>> [('사과', '1000원'), ('딸기', '2000원'), ('배', '3000원'), ('포도', '4000원'), ('키위', '5000원')]

dict(zip_obj)
>>> {'사과': '1000원', '딸기': '2000원', '배': '3000원', '포도': '4000원', '키위': '5000원'}

 

<여기서 잠깐>

 

저도 글을 작성하면서 알게된 점은, zip_obj를 한 번 사용하면 해당 주소에 들어있는 값이 사라진다는 것입니다.

 

그래서 위와 같이 zip_obj로 만들고, list나 dict로 만들어주는 것보다는 아래와 같이 한번에 코딩해주는 것이 좋겠습니다.

 

list_zip = list(zip(product_names, product_prices))

dict_zip = dict(zip(product_names, product_prices))

 

 

2. 리스트 3개 이상을 요소들끼리 묶어주는 법

 

이번엔 리스트 3개 이상을 묶어주는 방법을 알아보겠습니다. 똑같이 적용하면 되지 뭐가 문제냐고 생각하실 수 있는데요.

 

리스트 형태로 만들어주는 것은 전혀 문제가 없지만, 딕셔너리 형태로 만들어 줄 때는 문제가 생깁니다.

 

왜냐하면 딕셔너리는 Key: Value와 같이 단 2개씩만 묶어줄 수 있기 때문입니다.

딕셔너리 기본 형태 = {Key1:Value1, Key2:Value2, ...}

dic = {'name':'손생', 'age':'31'}

 

그러면 어떻게 해줘야할까요?

 

정답은 리스트 하나를 Key로 사용하고, 나머지 리스트들을 묶어서 Value로 사용하는 것입니다.

 

Key는 중복을 허용하지 않으므로, 중복되지 않을만한 제품 링크 주소를 Key로 사용해줍시다.

이런 식으로 묶어주시면 됩니다.

product_links = ['링크1','링크2','링크3','링크4','링크 5']
product_prices = ['1000원','2000원','3000원','4000원','5000원']
product_names = ['사과','딸기','배','포도','키위']

dict_product = dict(zip(product_links, zip(product_prices, product_names)))

 

<dict_product 출력 결과>

{'링크1': ('1000원', '사과'),
 '링크2': ('2000원', '딸기'),
 '링크3': ('3000원', '배'),
 '링크4': ('4000원', '포도'),
 '링크 5': ('5000원', '키위')}

 

 

3. 만들어진 딕셔너리 사용 방법

 

위에서 리스트를 이용해서 딕셔너리를 만드는 방법을 알아보았다면, 이제는 만든 딕셔너리를 사용하는 방법을 배워야겠죠?

 

이 부분은 딕셔너리 기초를 안다면 쉽게 이해할 수 있는 부분이므로 그냥 넘어가겠습니다.

# 제품 링크
key

# 제품 이름
dict_product[key][0]

# 제품 가격
dict_product[key][1]

 

 

4. 딕셔너리 응용 방법

 

아래의 코드는 특정 스마트스토어에서 새로 업로드 되는 제품만 텔레그램으로 전송받고자 했을 때 사용했던 코드입니다.

 

key에 저장된 제품 링크를 비교해서 새제품의 key : value만 필터링하여 저장 및 사용하기 위해서 딕셔너리를 사용하였죠. (글을 작성하면서 굳이 딕셔너리가 아니어도 zip 함수로 리스트를 만들고 인덱싱을 잘해주면 되겠다는걸 깨달았지만 그냥 넘어가도록 하겠습니다ㅎㅎ..)

 

위에서 만들었던 dict_product를 아래와 같이 딕셔너리 컴프리헨션과 결합하여 사용할 수 있답니다. 딕셔너리 컴프리헨션은 리스트 컴프리헨션을 알고계시다면 아주 쉽게 이해하실 수 있습니다.

 

new_products = {key:value for key, value in dict_product.items() if key not in old_products}

 

여기서 new_products에 저장된 값들은 for문을 이용해서 아래와 같이 가져올 수 있습니다.

 

<실제 응용 코드>

    # 새로운 메시지가 있으면 링크 전송
    if new_products:
        for key in new_products:
            bot.sendMessage(chat_id=chat_id,
                            text= new_products[key][0] + 
                            '\n\n' + '가격:' + new_products[key][1] + '원' + 
                            '\n\n' + key)

 


 

 

반응형
반응형

안녕하세요, 왕초보 코린이를 위한 코딩유치원에 오신 것을 환영합니다.

코딩유치원에서는 파이썬 기초부터 사무자동화, 웹크롤링, 데이터 분석 등의 다양한 패키지까지 초보자도 알기 쉽도록 내용을 정리해 놓았습니다.

업무는 물론 투자에도 도움이 될만한 전자공시시스템(DART) 텔레그램(Telegram) 관련 패키지도 배울 수 있으니 많은 관심 부탁드립니다.

 

 

예전에 파이썬의 장점인 간략한 코딩을 더욱 극대화하는 리스트 컴프리헨션에 대해서 알아보았는데요.

 

2021.11.21 - [파이썬 기초/중급 문법] - [파이썬 중급 문법] 리스트 컴프리헨션 간단 정리

 

오늘은 for 반복문 안에서 리스트 컴프리헨션을 사용할 때 주의할 점에 대해서 말씀드리려 합니다.


 

1. 리스트 컴프리헨션을 사용하는 이유

 

저는 리스트 컴프리헨션 문법을 웹크롤링을 하면서 자주 사용해 왔습니다. 어떤 값을 하나씩 리스트에 추가해줄 때 아주아주 유용하기 때문입니다.

 

<리스트 컴프리헨션을 사용하지 않은 코드>

new_contents=[]

for content in contents:
    if content not in old_contents:
        new_contents.append(content)

 

<리스트 컴프리헨션을 사용한 코드>

new_contents = [content for content in list_contents if content not in old_contents]

 

4줄의 코드가 이렇게 간단해 지니깐 안 쓸 이유가 없겠죠?

 

2. for문 안에서 리스트 컴프리헨션을 사용하지 않은 이유

 

하지만 최근 프로젝트에서 아래와 같이 리스트 컴프리헨션 문법을 사용하지 않았답니다.

 

그 이유는 for문을 돌 때 마다 리스트가 초기화 되어 버리기 때문이었습니다.

 

# 제품명을 담을 빈 리스트 선언
product_name = []

# for문을 이용해서 원하는 페이지에 접근, 정보 추출 후 리스트에 담기
for page_num in range(3):
    url = f'https://smartstore.naver.com/compuzone/category/ALL?st=RECENT&free=false&dt=IMAGE&page={page_num+1}&size=40'
    
    response = requests.get(url)
    soup = bs(response.text , 'html.parser')

    # css selector로 페이지 내의 원하는 정보 가져오기
    html_product = soup.select('strong.QNNliuiAk3')

    # 텍스트만 추출
    for i in html_product:
        product_name.append(i.get_text())

 

무슨 말인지 아직 감이 안오신다면 for문 밖에 product_name 리스트가 밖에서 선언된 것에 주목해보세요.

 

저의 목적은 for문을 돌면서 1, 2, 3페이지에 접속하고, 각 페이지에서 필요한 자료를 리스트에 계속 추가하는 것이었습니다.

 

하지만 아래와 같이 리스트 컴프리헨션 문법을 사용해버리면 product_name이라는 이름의 리스트를 for문 안에서 매번 새로 선언되어서 그 전에 쌓여있던 요소들이 모두 삭제되어 버립니다.

 

# for문을 이용해서 원하는 페이지에 접근, 정보 추출 후 리스트에 담기
for page_num in range(3):
    url = f'https://smartstore.naver.com/compuzone/category/ALL?st=RECENT&free=false&dt=IMAGE&page={page_num+1}&size=40'
    
    response = requests.get(url)
    soup = bs(response.text , 'html.parser')

    # css selector로 페이지 내의 원하는 정보 가져오기
    html_product = soup.select('strong.QNNliuiAk3')
	
    # 리스트 컴프리헨션 사용
    product_name = [i.get_text() for i in html_product]

 


글을 마치며,

 

이번 글은 누군가가에게는 당연한 이야기를 뭐 이렇게 길게 써놨는가 싶을 수 있겠지만, 코딩유치원의 취지에 잘 맞는 글이라고 생각이 듭니다.

 

아직 모르는 것이 많은 초보에게는 작은 돌뿌리도 큰 바위처럼 느껴지기 때문이죠.

 

코딩유치원생 여러분들은 코딩을 하시다가 모르는 부분이 생기시면 주저하지 마시고, 댓글 달아주세요.

 

제가 친절히 도와드릴테니까요~

반응형
반응형

안녕하세요, 왕초보 코린이를 위한 코딩유치원에 오신 것을 환영합니다.

코딩유치원에서는 파이썬 기초부터 사무자동화, 웹크롤링, 데이터 분석 등의 다양한 패키지까지 초보자도 알기 쉽도록 내용을 정리해 놓았습니다.

업무는 물론 투자에도 도움이 될만한 전자공시시스템(DART) 텔레그램(Telegram) 관련 패키지도 배울 수 있으니 많은 관심 부탁드립니다.

 

 

오늘은 파이썬의 장점인 간략한 코딩을 더욱 극대화하는 리스트 컴프리헨션에 대해서 공부해보겠습니다.


 

1. 리스트 컴프리헨션이란?

 

먼저 리스트 컴프리헨션(List Comprehension)의 의미를 알아봅시다.

 

리스트 컴프리헨션이란 '리스트 안에 표현식(계산식)과 for문, if문을 한줄에 넣어서 새로운 리스트를 만드는 것'을 말합니다.

 

# 일반적인 리스트 컴프리헨션

표현식(변수명이 포함되어 있음) for 변수명 in 기존 리스트

# if가 추가되어 필터링이 추가된 리스트 컴프리헨션

표현식(변수명이 포함되어 있음) for 변수명 in 기존 리스트 if 조건문

 

여기서 리스트라는 말이 들어가서 리스트만 사용할 수 있을 것 같지만, 앞서 배웠던 리스트(list), 튜플(tuple), 딕셔너리(dictionary), 셋트(set) 등의 컨테이너들도 모두 사용가능하답니다.

 

또한 표현식엔 수식 뿐만 아니라 함수도 사용 가능한 점도 알고 계시면 훨씬 더 간단한 코딩이 가능하답니다.

 

2. 리스트 컴프리헨션 사용법

 

간단한 예시를 통해서 리스트 컴프리헨션과 친해져 봅시다.

 

아래와 같은 리스트가 있습니다.

my_list = [0, 1, 2, 3]

 

이렇게 선언한 리스트 혹은 웹 크롤링을 통해서 받은 요소가 엄청 많은 리스트에 하나하나 어떤 처리를 하고 싶을 땐, 보통 이렇게 코딩을 하곤합니다.

 

# step1.처리(계산) 결과를 담을 새로운 리스트 선언
new_list = []

# step2.for문을 이용해서 계산을 수행하고, append()함수로 결과값을 새로운 리스트에 붙여넣기
for i in my_list:
    
    new_list.append(10*i)

 

결과를 확인해보면 아래와 같죠.

print(new_list)

>>> [0, 10, 20, 30]

 

리스트 컴프리헨션을 적용하면 단 한줄로 같은 결과를 낼 수 있답니다.

 

기존 코드와 비교하시면서 어떻게 3줄의 코드가 1줄의 코드로 바뀌었는지 꼭 이해하고 넘어가주세요.

 

new_list = [10*i for i in my_list]

 

 

3. 리스트 컴프리헨션(필터링) 사용법

 

 

앞서 언급하였 듯이 리스트 컴프리헨션에는 if문도 적용 가능합니다.

 

if문은 물론 if-else문도 사용 가능하답니다.

 

여기서 주의하실 점은 if문은 for문의 오른쪽, if-else문은 for문의 왼쪽에 사용한다는 점입니다.

 

<if문 사용 리스트 컴프리헨션 예시>

a = [1,2,3,4,5,6,7,8,9,10]

b = [i for i in a if i%2==0]

# if 조건을 and/or로 두 개 이상 쓸 수 있음
c = [i for i in a if i%2==0 and i%3==0]


print(b)
>>> [2, 4, 6, 8, 10]

print(c)
>>> [6]

 

<if-else문 사용 리스트 컴프리헨션 예시>

a = [1,2,3,4,5,6,7,8,9,10]

b = [i if i%2==0 else '홀수' for i in a ]

print(b)
>>> ['홀수', 2, '홀수', 4, '홀수', 6, '홀수', 8, '홀수', 10]

 

<if-else문 응용_ elif문 구현>

 

이해를 돕기 위한 if, elif, else 구문

if 짝수면 숫자를 출력

elif 짝수 아닌 것들 중, i가 10 이상이면 "홀수 중, 10 이상"이라는 문자열을 출력 (10은 10 이상이지만 짝수이므로 적용 안됨 --> elif)

else 그 외엔 모두 '홀수' 출력
 
a=[1,2,3,4,5,6,7,8,9,10,11]

b = [i if i%2==0 else '홀수' if i<10 else '홀수 중에 10 이상' for i in a ]

print(b)
>>> ['홀수', 2, '홀수', 4, '홀수', 6, '홀수', 8, '홀수', 10, '홀수 중에 10 이상']

 

오늘 준비한 내용은 여기까지입니다.

 

오늘도 공부하시느라 고생 많으셨습니다.


이 글이 도움이 되셨다면, 아래의 광고를 한 번씩만 눌러주시면 너무너무 감사하겠습니다!

반응형
반응형

안녕하세요, 왕초보 코린이를 위한 코딩유치원에 오신 것을 환영합니다.

코딩유치원에서는 파이썬 기초부터 사무자동화, 웹크롤링, 데이터 분석 등의 다양한 패키지까지 초보자도 알기 쉽도록 내용을 정리해 놓았습니다.

업무는 물론 투자에도 도움이 될만한 전자공시시스템(DART)나 텔레그램(Telegram) 관련 패키지도 배울 수 있으니 많은 관심 부탁드립니다.

 

 

오늘은 파이썬 프로그래밍의 초보에서 벗어나기 위한 첫번째 단계로, 클래스(class)에 대해 알아보겠습니다.

(이 글은 TCP 스쿨의 파이썬 강의를 참고하여 공부한 후 정리한 글입니다.)

 

이 글은 지난 글과 이어지는 글이므로, 지난 글을 읽고 읽으시면 이해에 도움이 됩니다.

 

https://coding-kindergarten.tistory.com/56

 

[파이썬 중급 문법] 클래스(class) 총정리 1편_객체,속성,메소드,인스턴스

안녕하세요, 왕초보 코린이를 위한 코딩유치원에 오신 것을 환영합니다. 코딩유치원에서는 파이썬 기초부터 사무자동화, 웹크롤링, 데이터 분석 등의 다양한 패키지까지 초보자도 알기 쉽도

coding-kindergarten.tistory.com

 

 


 

1. 초기화 메소드 ( __init__ )

 

지난 시간 class에 대해서 설명하며 예로 들었던 코드를 다시 보겠습니다. 사실 쉬운 이해를 위해서 아래와 같이 코딩했지만 당연히 실제로는 계좌번호나 계좌잔액에 정해진 값을 넣어 두진 않겠죠? 클래스를 1회용으로 만들지는 않을테니까요!

 

class ATM:                    # 클래스 선언

    계좌번호 = "123456789"      # 속성 선언
    계좌잔액 = "30000"


    def withdraw_all(self):   # 메소드 선언

        print(self.계좌번호 + "에서" + self.계좌잔액 + "을 인출하겠습니다.")
        

Coding_ATM = ATM()          # 인스턴스 생성

print(Coding_ATM.계좌번호)    # 인스턴스의 속성 가져오기
Coding_ATM.withdraw_all()   # 인스턴스의 메소드 호출

 

그래서 우리는 계좌번호와 계좌잔액을 입력받는 메소드를 가장 처음에 만들어줍니다. 이것도 코드로 보시죠.

이렇게 하면 인스턴스를 생성하고 setInfo 메소드를 이용해서 입력값을 받아서 모든 고객용으로 사용가능할 것입니다.

 

class ATM:                   

    def setInfo(self, 계좌번호, 계좌잔액):
    	
        self.계좌번호 = 계좌번호
        self.계좌잔액 = 계좌잔액

    def withdraw_all(self):

        print(self.계좌번호 + "에서" + self.계좌잔액 + "을 인출하겠습니다.")



Coding_ATM = ATM()   # 인스턴스 생성

Coding_ATM.setInfo('123456789', '30000')
Coding_ATM.withdraw_all()

 

하지만 이런 방식은 비효율적입니다. 만약 setInfo 메소드를 가장 먼저 호출해주지 않으면, withdraw_all 메소드에서 사용해야할 인수가 입력되지 않았으므로 오류가 발생하기 때문이죠. 거기다가 코드도 길어지는 단점이 있죠.

 

그래서 지금 배울 초기화 메소드(initialize method)를 사용해줍니다. 앞으로 클래스를 만들 땐 꼭 초기화 메소드를 사용한다고 생각하시면 되겠습니다. 파이썬에서 초기화 메소드의 이름은 __init__으로 고정되어 있습니다.

 

class ATM:                   

    def __init__(self, 계좌번호, 계좌잔액):
    	
        self.계좌번호 = 계좌번호
        self.계좌잔액 = 계좌잔액

    def withdraw_all(self):

        print(self.계좌번호 + "에서" + self.계좌잔액 + "을 인출하겠습니다.")



Coding_ATM = ATM('123456789', '30000')   # 인스턴스 생성 시, 인수를 입력해주어야함

Coding_ATM.withdraw_all()

 

 

2. 클래스 변수 / 인스턴스 변수

 

변수가 선언된 위치에 따라 변수의 유효 범위가 달라지며, 이에 따라 다음과 같이 구분할 수 있습니다.

 

1) 클래스 변수(class variable)

   : 해당 클래스에서 생성된 모든 인스턴스가 값을 공유하는 변수

 

2) 인스턴스 변수(instance variable)

   : __init__() 메소드 내에서 선언된 변수로 인스턴스가 생성될 때마다 새로운 값이 할당되는 변수

 

class ATM:                      # 클래스 선언

    계좌번호 = "123456789"        # 이 방식이 클래스 변수
    계좌잔액 = "30000"
    
    
    def __init__(self, 계좌번호, 계좌잔액):
    	
        self.계좌번호 = 계좌번호    # 이 방식이 인스턴스 변수
        self.계좌잔액 = 계좌잔액    

 

예를 들어, 게임회사의 프로그래머가 게임 캐릭터를 만들 때 계속 사용할 클래스를 만드는 상황을 가정해봅시다.

게임 캐릭터가 공통적으로 가지는 특성은 클래스 변수로 설정해주고, 캐릭터마다 개성을 부여해줄 부분은 인스턴스 변수로 설정해주는 것을 생각해 볼 수 있겠습니다.

 

 

3. 상속

 

여기서의 상속(inheritance)은 여러분들이 아는 그 상속이 맞습니다. 부모가 자식한테 재산을 물려주는 것 말입니다.

여기서 다른 것은 사람이 아니라 클래스인 점이죠. 이 상속의 개념을 이용하면 이미 존재하는 클래스의 속성과 메소드를 모두 그대로 사용할 수 있습니다. 거기다가 기능을 추가할 수도 있답니다.

 

용어를 잠깐 설명드리면, 이미 존재하던 클래스를 부모 클래스(parent class) 또는 기초 클래스(base class)라고 부르며,

상속을 통해 새롭게 생성되는 클래스를 자식 클래스(child class) 또는 파생 클래스(derived class)라고 부릅니다.

 

상속의 사용 예를 들어보겠습니다. 서로 개과와 고양이과로 생김새는 다르지만 새끼를 낳는 ‘포유류’라는 공통적인 특징을 갖는 것입니다.

만약 게임 안에서 개와 고양이를 만들 때, 포유류 클래스를 만들어서 다리는 4개, 새끼를 나음, 눈 2개 등의 특징을 부여하고, 그 클래스를 상속받아서 각각의 개 클래스, 고양이 클래스를 세부적으로 만들어주는 것이죠.

 

클래스 상속은 아래와 같이 간단하게 가능합니다. 이렇게 상속을 통해 만들어진 자식 클래스를 이용해 만든 인스턴스는, 부모 클래스 안의 속성과 매소드를 모두 활용 가능합니다. 상속 그리 어렵지 않죠?

 

class 자식클래스명(부모클래스명):

 

4. 메소드 오버라이딩

 

위에서 배운 상속이 어떤 도면을 복사 붙여넣기 해서 내용을 추가한 것이라면, 메소드 오버라이딩은 상속한 후에 기존 내용을 수정한 것입니다. 즉, 상속한 다음에 메소드를 같은 이름으로 재정의 해주는 것입니다.

 

# 부모 클래스 (일반 새)
class Bird:

    def __init__(self):
        self.flying = True  

    def birdsong(self):
        print("짹짹")    


# 자식 클래스 1 (참새)  --> 상속
class Sparrow(Bird):


# 자식 클래스 2 (닭) --> 상속 후 메소드 오버라이딩
class Chicken(Bird):

    def birdsong(self):
        print("꼬끼오")   


# 객체화
my_sparrow = Sparrow()
my_chicken = Chicken()


# 그냥 상속과 메소드 오버라이딩의 비교
my_sparrow.birdsong()
my_chicken.birdsong()


<결과>

짹짹
꼬끼오

 

 

자세히 보시면 birdsong 메소드를 실행시켰을 때 차이가 생깁니다.

 

단순히 Bird 클래스를 상속받은 Sparrow 클래스는 birdsong 메소드를 실행시켰을 때 "짹짹"을 출력하고,

 

Bird 클래스의 속성을 상속받은 후 birdsong 메소드를 재정의(메소드 오버라이딩) 해준 Chicken 클래스는 "꼬끼오"를 출력하죠?

 


혹시 설명이 잘 이해가 가지 않거나 질문사항 있으시면 댓글 달아주세요!

 

감사합니다.

 

 

 

반응형
반응형

안녕하세요, 왕초보 코린이를 위한 코딩유치원에 오신 것을 환영합니다.

코딩유치원에서는 파이썬 기초부터 사무자동화, 웹크롤링, 데이터 분석 등의 다양한 패키지까지 초보자도 알기 쉽도록 내용을 정리해 놓았습니다.

업무는 물론 투자에도 도움이 될만한 전자공시시스템(DART) 텔레그램(Telegram) 관련 패키지도 배울 수 있으니 많은 관심 부탁드립니다.

 

오늘은 파이썬 프로그래밍의 초보에서 벗어나기 위한 첫번째 단계로, 클래스(class)의 개념에 대해 알아보겠습니다.

 

새로운 개념을 이해할 때에는 원래 알고 있는 개념에서 덧붙이거나 비유를 통해서 이해하는 것이 효율적이라고 생각합니다.

비유를 통해 최대한 쉽게 설명해볼테니 차근차근 따라와주세요.

 


 

1. 클래스의 개념

 

클래스는 기초문법 강의에서 배운 함수의 개념과 유사하면서도 다릅니다.

 

출처. 프로그래머가 필요한 수학 (brunch)

 

함수란 아래의 그림의 빵 만드는 기계처럼 '밀가루(입력)을 받아서 의도된 프로세스를 통해 빵(출력)을 내보내는 무엇'라고 이해한다면,

클래스 빵 만드는 기계(함수) 입력과 출력(변수)의 정보를 담은 설계도입니다.

 

위의 설명만 이해하셔도 클래스의 절반은 파악하신 것이니 꼭 이해하고 넘어가셨으면 좋겠습니다.

 

 

우리는 이 설계도가 있다면 얼마든지 빵 만드는 기계를 만들 수 있는 것이죠.

또한 이 설계도를 내용을 추가하거나 변경하여 새로운 기능의 빵 만드는 기계를 만들 수 있습니다.

 

위의 내용은 다음 시간에 상속(inheritance)메소드 오버라이딩(method overriding)의 개념을 공부하며 더 자세히 다루어 보겠습니다.

 

 

2. 클래스 기초

 

설계도를 활용 하려면 도면해독법에 대한 지식이 필요하듯이 클래스를 활용하기 위한 기본 개념들이 필요합니다.

 

1) 객체

프로그래밍이 처음이시거나 C언어를 공부하셨던 분들은 객체(object)란 용어가 생소하실텐데요.

객체란 그냥 실체가 있는 무엇이라는 뜻을 있어보이게 표현한 말입니다. 현재 사용하고 계신 컴퓨터나 휴대폰, 앉아있는 의자, 혹은 나 자신 까지도 모두 객체라고 생각할 수 있습니다.

 

이 객체란 개념은 설계도만 존재하고 실체는 존재하지 않는 상태인 클래스와 엮어서 설명되곤 합니다.

여러 책에서 붕어빵 틀(클래스)과 붕어빵(객체)으로 설명합니다만 개인적으로 정확한 비유는 아니라고 생각합니다.

어떻게 보면 붕어빵 틀도 실체일테니까요.

 

2) 속성과 메소드

앞서 클래스를 빵 만드는 기계(함수)와 입력과 출력(변수)의 정보를 담은 설계도라고 설명했습니다.

지금 배울 속성(attribute)과 메소드(method)는 각각 설계도에 표시되어 있는 변수와 함수라고 이해하시면 됩니다.

 

클래스의 변수 = 속성 (attribute)

클래스의 함수 = 메소드 (method)

 

예를 들어, 현금자동인출기(ATM)를 클래스로 작성한다면,

속성으로는 계좌번호, 잔액, 인출금액, 메소드로는 입금하기, 출금하기, 이체하기 등을 만들 수 있을 것입니다.

 

3) 클래스 선언

class의 선언은 'class 클래스명:'으로 선언해줍니다.

 

만약 아래와 같이 클래스를 선언해주면 '클래스명'이라는 이름의 아무 내용도 담기지 않은 설계도가 생성된다고 생각하시면 됩니다.

마치 CAD(전자도면)을 새로 만들고 이름만 정해서 저장해준 느낌입니다.

 

class 클래스명:
	pass

 

다음으로는 클래스 안에 내용을 채워보겠습니다. 이해를 위한 코드이므로 실제로는 작동되지 않습니다.

 

class ATM:                    # 클래스 선언

    계좌번호 = "123456789"      # 속성 선언
    계좌잔액 = "30000"


    def withdraw_all(self):   # 메소드 선언

        print(self.계좌번호 + "에서" + self.계좌잔액 + "을 인출하겠습니다.")

 

우리가 돈을 뽑는 ATM 클래스를 만들어보았습니다.

 

속성으로는 계좌번호와 계좌잔액을 가지며, 메소드로는 계좌잔액을 모두 인출하는 withdraw_all 메소드를 가지는 클래스입니다.

 

여기서 self라는 생소한 개념이 보입니다. 클래스를 사용하려면 이 self에 대한 이해가 필수적입니다.

 

self란?

메소드 선언 시 사용된 self는 객체가 자기 자신을 참조하는데 사용하는 매개변수입니다.

self를 사용하면, 메소드에서 클래스에 정의된 모든 속성 및 다른 메소드에 접근할 수 있습니다.

 

파이썬에서는 메소드를 선언할 때 첫 번째 매개변수로 반드시 self를 명시하도록 하고 있으며, 메소드를 호출할 때는 self 매개변수에 아무런 인수를 전달하지 않아도 됩니다.

 

 

4) 인스턴스 생성

인스턴스란 클래스를 기반으로 생성된 객체를 가리킵니다. 그냥 객체라고 해도 되겠지만 특별히 어떤 클래스의 객체라는 것을 말해주는 느낌이랄까요. 마치 영희(객체)라는 사람이 있는데, 굳이 미영이의 딸(OO 클래스의 인스턴스)이라고 부르는 느낌이라고 생각하시면 되겠습니다. 완벽한 예는 아닌듯하지만 느낌만 가져가시면 좋겠습니다.

 

class ATM:                  # 클래스 선언

    계좌번호 = "123456789"    # 속성 선언
    계좌잔액 = "30000"


    def withdraw_all(self): # 메소드 선언

        print(self.계좌번호 + "에서" + self.계좌잔액 + "을 인출하겠습니다.")
        

Coding_ATM = ATM()          # 인스턴스 생성

print(Coding_ATM.계좌번호)    # 인스턴스의 속성 가져오기
Coding_ATM.withdraw_all()   # 인스턴스의 메소드 호출

 

위의 코드에서 방금 만들어준 ATM 클래스를 가지고 Coding_ATM이라는 객체를 생성해주었습니다.

클래스명에 소괄호( )를 붙여서 해당 클래스의 인스턴스를 생성할 수 있습니다.

 

여기서, 'Coding_ATM은 ATM의 인스턴스다'라고 말할 수 있습니다.

 

Coding_ATM.계좌번호나 Coding_ATM.withdraw_all( )과 같이 생성된 인스턴스에 닷(.) 연산자를 사용하면 해당 클래스의 속성이나 메소드를 호출할 수 있습니다.

 


오늘은 클래스의 가장 기본에 대해서 다루어보았습니다.

 

다음 시간에는 클래스에 대한 조금더 깊은 내용을 다루어보겠습니다.

 

 

반응형

+ Recent posts