스터디/파이썬 스터디 강의자료

[4팀/이제은] 8차시 파이썬 스터디 - 객체 지향 프로그래밍

알 수 없는 사용자 2023. 5. 18. 09:03

8차시_객체지향_과제.pdf
0.58MB
8차시_객체지향_강의안.pdf
0.97MB

01 객체 지향 프로그래밍의 이해

>객체 지향 프로그래밍을 배우는 이유

 

함수를 배울 때와 같이, 여러 사람이 프로그램을 개발할 때 어떤 방법이 좋은지에 대한 고민으로부터 시작! 👉다른 사람이 작성한 코드를 사용하기 위해 객체 지향 프로그래밍을 사용!

 

>객체와 클래스

 

객체(object)

  • 실생활에 존재하는 실제적인 물건 또는 개념
  • 속성(attribute)와 행동(action)으로 구성
  • 이때 속성은 변수로, 행동은 함수로 정의
    • ex) 인공지능 축구 프로그램을 만든다는 가정
    • → 어떤 종류의 객체가 필요한지 생각해야 한다.
    • → 객체들을 위한 설계도를 작성해야 한다. (= class)

 

클래스(class)

  • 객체가 가져야 할 기본 정보를 담은 코드로 일종의 설계도 코드
  • 객체의 정보를 클래스에 담고, 실제 생성되는 객체에는 객체의 이름을 할당한다. (→ 실제로 생성되는 객체 = instance)

DOG 클래스와 DOG 인스턴스 (클래스 : 붕어빵 틀, 인스턴스 : 붕어빵)

 

02 파이썬의 객체 지향 프로그래밍

>클래스 구현하기

더보기

축구 선수 클래스를 파이썬에서 구현하기

*class 선언

파이썬에서의 클래스 선언의 기본 코드 템플릿은 다음과 같습니다.

  1. 먼저 예약어인 class를 코드의 맨 앞에 입력합니다.
  2. 그리고 만들고자 하는 클래스 이름을 작성합니다.
  3. 그 다음 상속받아야 하는 다른 클래스의 이름을 괄호 안에 넣습니다. (여기서 상속이란 기존에 만든 클래스의 특징을 그대로 이어받아 사용하는 것을 말합니다. 객체 지향 프로그래밍의 장점 중 하나인 재사용성을 용이하게 해줍니다. )

++파이썬에서의 작명기법++

변수와 함수는 snack_case

클래스는 CamelCase

 

*속성의 선언

축구 선수 클래스를 구성해보도록 합시다.

  • _ _ init _ _ ( ) : 속성에 대한 정보 선언
  • 예시코드
class SoccerPlayer(object):
    def__init__(self, name, position, back_number):
        self.name = name
        self.position = position
        self.back_number = back_number

- _ _ init _ _ ( ) 함수는 이 클래스에서 사용할 변수를 정의하는 함수입니다.

- _ _ init _ _ ( ) 함수의 첫 번째 매개변수는 반드시 self 변수를 사용해야 합니다. (self 변수는 클래스에서 생성된 인스턴스에 접근하는 예약어)

- self 뒤의 매개변수들은 실제로 클래스가 가진 속성으로 축구 선수의 이름, 포지션, 등번호 등입니다. 이 값들은 실제로 생성되는 인스턴스에 할당됩니다.

 → 할당되는 코드는 self.name = name (name 변수에 매개변수로 입력된 name이라는 값을 할당한다는 뜻)

 

*함수의 선언

축구 선수가 하는 동작인 ‘등번호 교체’라는 행동을 구성해보도록 합시다.

class SoccerPlayer(object):
    def change_back_number(self, new_number):
        print("선수의 등번호를 변경한다: From %d to %d" % (self .back_number, new_number))
        self.back_number = new_number

- 기존의 함수와 같이 함수의 이름과 매개변수를 사용합니다. 

- 매개변수에 self를 !반드시! 넣어야합니다. (self가 있어야만 실제로 인스턴스가 사용할 수 있는 함수로 선언)

 

*_의 쓰임

_ 1개 : 이후에 쓰이지 않을 변수에 특별한 이름을 부여하고 싶지 않을 때 사용

_ _ 2개 : 특수한 예약 함수나 변수를 의미함

 

 

 

>인스턴스 사용하기

더보기

생성된 클래스를 인스턴스로 호출해 사용하는 방법을 알아봅시다!

인스턴스 : 클래스에서 실제적인 데이터가 입력되어 사용할 수 있는 형태의 객체

→ 여러 가지 재료가 들어간 붕어빵 그 자체

 

앞에서 클래스를 구현할 때 SoccerPlayer라는 이름으로 생성했습니다.

이 클래스는 그저 기본 설계도(붕어빵 틀) → 선수의 이름이나 등번호가 아직 할당X

실제로 인스턴스를 사용하기 위해서는 이러한 정보를 할당한 상태로 사용해야 합니다!

 

*인스턴스 호출

- 클래스 이름을 호출

- 앞에서 정의했던 _ _ init _ _ ( ) 함수의 매개변수에 맞투어 값을 입력

- self 변수에는 아무런 값도 할당하지 않음

- 전체 SoccerPlayer 코드

# 전체 SoccerPlayer 코드
class SoccerPlayer(object):
    def __init__(self, name, position, back_number):
        self.name = name
        self.position = position
        self.back_number = back_number

    def change_back_number(self, new_number):
        print("선수의 등번호를 변경한다: From %d to %d" % (self.back_number, new_number))
        self.back_number = new_number

    def __str__(self):
        return "Hello, My name is %s. I play in %s in center." % (self.name, self.position)

 # SoccerPlayer를 사용하는 instance 코드
jinhyun = SoccerPlayer("Jinhyun", "MF", 10)

print("현재 선수의 등번호는:", jinhyun.back_number)
jinhyun.change_back_number(5)
print("현재 선수의 등번호는:", jinhyun.back_number)
현재 선수의 등번호는: 10
선수의 등번호를 변경한다: From 10 to 5
현재 선수의 등번호는: 5

- 14행에서 jinhyun = SoccerPlayer("Jinhyun", "MF", 10) 코드로 인스턴스를 새롭게 만들었습니다. 

- 만들어진 인스턴스인 jinhyun은 name, position, back_mimber에 각각 Jinhyiin, MF, 10이 할당되었습니다. 할당된 값을 만들어진 인스턴스에서 사용하기 위해서 jinhyun.back_number 형식으로 인스턴스 내의 값을 호출하고 있습니다.

 

주의

인스턴스가 생성된 후에는 해당 인스턴스의 이름으로 값을 할당하거나 함수를 부르면 되지만, 클래스 내에서는 self로 호출된다. 즉, 생성된 인스턴스인 jinhyun과 클래스 내 self가 같은 역할을 하는 것이다.

 

*함수 호출

함수를 호출할 때에도 인스턴스의 이름과 함수명 사용합니다.

위 코드에선 jihyun.change_back_number(5)를 사용해 클래스 내의 함수를 사용했습니다. 위 코드에 이어 print(jinhyun) 을 입력하면 다음과 같은 결과가 출력됩니다.

Hello, My name is Jinhyun. I play in MF in center.

 

 

>클래스를 사용하는 이유

🧐 이처럼 복잡한 객체 지향 프로그래밍의 개념을 왜 사용하는 것일까요?

→ 핵심은, 코드를 다른 사람이 손쉽게 사용할 수 있도록 설계하기 위함입니다!

  1. 데이터를 변환하거나 데이터베이스에 저장하는 등의 역할이 필요할 때
  2. 코드를 좀 더 손쉽게 선언하고자 할 때

 

03 객체 지향 프로그래밍의 특징

더보기

💡객체 지향 프로그래밍의 기본 철학은 실생활을 모델링한다는 개념

>상속

상속(inheritance) : 클래스에 정의된 속성과 메서드를 자식 클래스가 물려받아 사용

→ 이름 그대로 무언가를 내려받는 것을 뜻합니다.

→ 이를 통해 코드의 재상속성과 유지보수성을 높일 수 있습니다.

 

class ChildClass(object)
    pass

괄호 안에 들어간 것이 ChildClass의 부모 클래스입니다. 여기서는 object가 부모 클래스.

object = 파이썬에서 사용하는 가장 기본 객체

파이썬이 객체 지향 프로그래밍이기 때문에 모든 변수가 객체가 된다!

 

>>> a = 'abc'
>>> type(a)
<class 'str'>

지금까지 문자열을 자료형 중 하나라고 정의하고 문자열형이라고 불렀지만 내부적으로는 객체(class)로 처리된 것을 확인할 수 있습니다!

 

- 상속 더 알아보기

>>> class Person(object):
        def __init__(self, name, age):
            self.name = name
            self.age = age
..
>>> class Korean(Person):
        pass
...
>>> first_korean = Korean("Jeeun", 22)
>>> print(first_korean.name)
Jeeun

Person 클래스 생성

_ _ init _ _ ( ) 함수를 만들어 name과 age에 관련된 정보를 입력하도록 했습니다.

Korean 클래스 생성

Person 클래스를 상속받았습니다. pass는 별도의 내용 없이 클래스만 존재한다는 의미입니다. 

(별도의 의미 없이 Korean 클래스 인스턴스를 만든 것)

상속받았기 때문에 Person 클래스에서 생성한 변수를 그대로 사용할 수 있는 것을 확인할 수 있습니다.

 

>다형성

다형성(polymorphism) : 같은 이름의 메서드가 다른 기능을 하는 것

 

[예시] 인터넷에서 데이터를 모으는 프로그램, 크롤러

<단계>

  1. 부모 크롤러 클래스 제작하고 do_crawling이라는 함수 생성
  2. Crawler 클래스를 상속시켜 NaverCrawler와 DaumCrawler를 생성 (이 때 두 자식 클래스는 모두 do_crawling 함수를 갖게 됨)

같은 이름이지만 구현 내용은 다르다! = 구현되는 내부 로직에 차이가 있다! = 다형성

 

 

>가시성

가시성(visibility) : 객체의 정보를 볼 수 있는 레벨을 조절하여 객체의 정보 접근을 숨기는 것

가시성 = 캡슐화 = 정보 은닉

 

*파이썬에서의 객체의 재사용

- 재사용을 위해 각 객체가 무슨 역할을 하는지 알아야 함

- 그러나 세부적인 구현 내용은 알 필요 없음 (단지 사용법만 필요)

- 즉, 객체의 매개변수 인터페이스만 명확히 알면 사용할 수 있다!

캡슐화 : 객체의 세부 내용은 모른 채 객체의 사용법만 알고 사용하는 것

 

*캡슐화를 사용해햐 하는 이유

  1. 클래스를 설계할 때 클래스 간 간섭 및 정보 공유를 최소화하여 개별 클래스가 단독으로도 잘 동작할 수 있도록 해야하기 때문
  2. 사용자 입장에서는 상세한 내용을 모르더라도 인터페이스를 이해하면 클래스를 쉽게 사용할 수 있기 때문