Python Object Oriented Programming

김선재·2021년 12월 9일
0

AI Tech

목록 보기
1/8
post-thumbnail

객체지향 프로그래밍 개요

Object-Oriented Programming, OOP

  • 클래스: 설계도

  • 객체: 실생활에서 일종의 물건

    • 속성( Attribute )와 행동( Action )을 가짐
    • 예를 들어

      의자라고 할 때

      • 속성: 색, 다리의 개수, 다리의 모양 등
      • 행동: 의자가 움직여지는 형태, 색이 바뀌는 것 등 수동적인 행동들

      축구 팀이라고 할 때

      • 속성: 선수 - 선수 이름, 포지션, 소속팀
        팀 - 팀 이름, 팀 연고지, 팀소속 선수
      • 행동: 선수 - 공을 차다, 패스하다
        심판 - 휘슬을 불다, 경고를 주다
  • 클래스와 객체에 대해 많이 이야기한다

    ex) 붕어빵 틀과 만들어지는 붕어빵

Class 구현하기 in python

축구 선수 정보를 class로 구현하기
-class 선언 형태

  • 속성에 관해 추가할 때는 init을 사용
    • self: 생성된 인스턴스 자기 자신을 의미

📍 설계도 부분

class SocerPlayer(object):
    def __init__ (self, name : str, position : str, back_number : int):
        self.name = name
        self.position = position
        self.back_number = back_number
    
    def __str__(self):
        return "Hello, My name is %s. I play in %s in center " % \
                (self.name, self.position)
    
    def __add__(self, other):
        return self.name + other
    
    def change_back_number(self, new_number):
        print('선수의 등번호를 변경합니다 : From %d to %d' % \
              (self.back_number, new_number))
        self.back_number = new_number

📍 설계도를 바탕으로 만들어내는 객체

abc = SocerPlayer('son', 'FW', 7)
park = SocerPlayer('park', 'WF', 13)
son.change_back_number(10)

~~>
선수의 등번호를 변경합니다 : From 7 to 10

print(son)

~~>
Hello. My name is son. My back number is 10

구현 가능한 OOP 만들기 - 노트북

Note를 정리하는 프로그램

  • 사용자는 Note에 뭔가를 적을 수 있다.
  • Note에는 Content가 있고, 내용을 제거할 수 있다.
  • 두 개의 노트북을 합쳐 하나로 만들 수 있다.
  • Note는 Notebook에 삽입된다.
  • Notebook은 Note가 삽일 될 때 페이지를 생성하며, 최고 300페이지까지 저장 가능하다
  • 300 페이지가 넘으면 더 이상 노트를 삽입하지 못한다
class Note(object):
	def __init__(self, content = None):
		self.content = content

	def write_content(self, content):
		self.content = content

	def remove_all(self):
		self.content = ""

	def __add__(self, other):
		return self.content + other.content

	def __str__(self):
		return self.content
class NoteBook(object):
	
    def __init__(self, title):
        self.title = title
        self.page_number = 1
        self.notes = {}

	
    def add_note(self, note, page = 0):
        if self.page_number < 300:
	        if page == 0:
    		    self.notes[self.page_number] = note
        		self.page_number += 1
        	else:
        		self.notes = {page : note}
        		self.page_number += 1
        else:
        	print("Page가 모두 채워졌습니다.")
        
    def remove_note(self, page_number):
      	if page_number in self.notes.keys():
       		return self.notes.pop(page_number)
       	else:
       		print("해당 페이지는 존재하지 않습니다")
        
    def get_number_of_pages(self):
        return len(self.notes.keys())

📍 불러와서 사용하기

from teamlab_note import Note
from teamlab_note import NoteBook

OOP Characteristics

객체 지향 언어의 특징

✨ Inheritance( 상속 )

  • 부모클래스로 부터 속성과 Method를 물려받은 자식 클래스를 생성하는 것
class Person(object): # 부모 클래스 Person 선언
    def __init__(self, name, age, gender):
        self.name = name
        self.age = age
        self.gender = gender
    def about_me(self): # Method 선언
        print("저의 이름은 ", self.name, "이구요, 제 나이는 ", str(self.age), "살입니다.")
myPerson = Person('John', 23, 'Male')
myPerson.about_me()

~~>
저의 이름은 John 입니다. 나이는 23 살이고 Male 입니다.

📍 super를 통해 부모클래스에 있는 정보를 가져와 사용

class Employee(Person): # 부모 클래스 Person으로 부터 상속
    def __init__(self, name, age, gender, salary, hire_date):
        super().__init__(name, age, gender) # 부모객체 사용
        self.salary = salary
        self.hire_date = hire_date # 속성값 추가
    
    def do_work(self): # 새로운 메서드 추가
        print("열심히 일을 합니다.")
    
    def about_me(self): # 부모 클래스 함수 재정의
        super().about_me() # 부모 클래스 함수 사용
        print("제 급여는 ", self.salary, "원 이구요, 제 입사일은 ", self.hire_date, 
        " 입니다.")
myEmpolyee = Employee('Daeho', 34, 'Male', 300000, '2012/12/12')
myEmpolyee.about_me()

~~>
저의 이름은 Daeho 입니다. 나이는 34 살이고 Male 입니다.
제 급여는 300000 원 이구요, 제 입사일은 2012/12/12 입니다.

✨ Polymorphism( 다형성 )

  • 같은 이름 메소드의 내부 로직을 다르게 작성
  • Dynamic Typing 특성으로 인해 파이썬에서는 같은 부모클래스의 상속에서 주로 발생
class Animal:
    def __init__(self, name): # Constructor of the class
        self.name = name
    def talk(self): # Abstract method, defined by convention only
        raise NotImplementedError("Subclass must implement abstract method")

class Cat(Animal):
    def talk(self):
        return 'Meow!'
    
class Dog(Animal):
    def talk(self):
        return 'Woof! Woof!'
animals = [Cat('Missy'),
           Cat('Mr. Mistoffelees'),
           Dog('Lassie')]
           
for animal in animals:
    print(animal.name + ': ' + animal.talk())
    
~~>
Missy:Meow!
Yeorem:Woof!

✨ Visibility( 가시성 )

  • 객체의 정보를 볼 수 있는 레벨을 조절하는 것

  • 누구나 객체 안에 모든 변수를 볼 필요가 없음

    • 객체를 사용하는 사용자가 임의로 정보수정
    • 필요 없는 정보에는 접근 할 필요가 없음
    • 만약 제품으로 판매한다면? 소스의 보호
  • 캡슐화 또는 정보 은닉( Information Hiding)

  • Class를 설계할 때 클래스 간 간섭 / 정보공유의 최소화

📍 Example 1

  • Product 객체를 Inventory 객체에 추가
  • Inventory에는 오직 Product 객체만 들어감
  • Inventory에 Product가 몇 개인지 확인이 필요
  • Inventory에 Product items는 직접 접근이 불가
class Product(object):
    pass
class Inventory(object):
    def __init__(self):
        self.__items = []    # Private 변수로 선언 -> 타객체가 접근 못함
    def add_new_item(self, product):
        if type(product) == Product:
            self.__items.append(product)
            print("new item added")
        else:
            raise ValueError("Invalid Item")
            
    def get_number_of_items(self):
        return len(self.__items)
my_inventory = Inventory()
my_inventory.add_new_item(Product())
my_inventory.add_new_item(Product())
my_inventory

~~>
new item added
new iten added
<__main__.Inventory at 0x------------->

my_inventory.items.append('abc')
my_inventory.items

~~>
[<__main__.Inventory at 0x------------->
<__main__.Inventory at 0x------------->
'abc',
'abc']

📍 Example 2

  • Product 객체를 Inventory 객체에 추가
  • Inventory에는 오직 Product 객체만 들어감
  • Inventory에 Product가 몇 개인지 확인이 필요
  • Inventory에 Product items 접근 허용
class Inventory(object):
    def __init__(self):
        self.__items = []

    @property    # property decorator 숨겨진 변수를 반환하게 해줌
    def items(self):
        return self.__items
my_inventory = Inventory()
my_inventory.add_new_item(Product())
my_inventory.add_new_item(Product())
print(my_inventory.get_number_of_items())

~~>
new item added
new item added
# 접근이 불가능하기 때문에 error가 발생한다

items = my_inventory.items
items.append(Product())
print(my_inventory.get_number_of_items())

~~>
<__main__.Inventory at 0x------------->

decorate

First-class Object

  • 일등함수 또는 일수객체
  • 변수나 데이터 구조 모두에 할당이 가능한 객체
  • 파라메터로 전달이 가능하고 리던 값으로도 사용
profile
data science!!, data analyst!! ///// hello world

0개의 댓글