📚 STUDY/AI

인공지능(AI) 기초 다지기: Python Object Oriented Programming(파이썬 객체 지향 프로그래밍 언어) (2)

삶감 2022. 8. 1. 21:17

Python Object Oriented Programming(파이썬 객체 지향 프로그래밍 언어) (2)

🔗 강의 바로가기

💻 OOP Implementation Example

구현 가능한 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())

💻 OPP의 특징

실제 세상을 프로그램으로 모델링

  • Inheritance 상속
  • Polymorphism 다형성
  • Visibility 가시성 (데이터를 얼마나 볼 수 있는가.)



1. Inheritance 상속

  • 부모 클래스로부터 속성과 메서드를 물려받은 자식클래스를 생성하는 것

picture 2
Korean이라는 클래스가 Person이라는 클래스를 상속 받았기 때문에 Person의 속성을 그대로 사용할 수 있다.



super()의 사용

picture 3
부모 클래스를 부르는 메소드. self와 유사하게 사용한다.
super()을 사용해 부모 클래스의 속성에 접근할 수 있다.





2. Polymorphism 다형성

picture 4

  • 같은 이름의 메소드의 내부 로직을 다르게 작성 (같은 이름이지만 다른 동작을 함)
    picture 5

  • Dynamic Typing 특성으로 파이썬에서는 같은 부모클래스의 상속에서 주로 발생함

  • 중요한 OPP 개념이지만 너무 깊이 알 필요 X




3. Visibility 가시성

  • 객체의 정보를 볼 수 있는 레벨을 조절하는 것
  • 누구나 객체 안의 모든 변수를 볼 필요가 없음
    • 객체를 사용하는 사용자가 임의로 정보 수정
    • 필요없는 정보에는 접근할 필요가 없음
    • 제품으로 판매할 경우, 소스를 보호해야함 (JAVA의 경우)


(+) 캡슐화 (Encapsulation)

  • 캡슐화 또는 정보 은닉(Information Hiding)
  • Class 설계 시, 클래스 간 간섭/정보공유 최소화
  • 캡슐을 던지듯, 인터페이스만 알아서 써야함 (인터페이스만 알아도 정보를 쉽게 쓸 수 있음)



3-1. Private 변수

picture 7

  • __(언더바 2개)를 변수 앞에 붙여주면 타객체가 접근하지 못함

    • 실제로는 다른 개념이기는 하나 기능상으로는 private의 기능을 수행함
  • private 변수에 접근하는 방법 : @property 데코레이터 decorator 사용

      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())
      items = my_inventory.items #property decorator로 함수를 변수처럼 호출

    @property 데코레이터를 사용하면 내부적으로 접근이 가능해져서 private한 값을 반환할 수 있게 된다.

  • 보통 return self.__items 처럼 직접적인 값을 반환하고 수정하면 private한 값이 수정되기 때문에 @property를 이용하여 반환할 때, 값을 복사하여 반환한다

💻 decorate

1. 이해하기 위한 개념들

  • first-class objects

    • 일등함수 또는 일급 객체

    • 변수나 데이터 구조에 할당이 가능한 객체

    • 파라미터로 전달이 가능, 반환 값으로 사용

    • 파이썬의 모든 함수는 일급함수임

      def square(x):
          return x*x
      
      f = square # 함수를 변수로 사용
      f(5)
  • inner function

    • 내제 함수

    • 함수 내에 또 다른 함수가 존재

      def print_msg(msg):
          def printer():
              print(msg)
          printer()
      
      print_msg("Hi") 
    • closures : inner function을 return값으로 반환

      def print_msg(msg):
          def printer():
              print(msg)
          return printer
      
      another = print_msg("Hi")
      another() 



2. decorator function

  • 복잡한 클로져 함수를 간단하게 표현할 수 있음

    def star(func):
      def inner(*args, **kwargs):
          print("*" * 30)
          func(*args, **kwargs)
          print("*" * 30)
      return inner
    
    @star # printer 함수가 star의 변수 func로 들어가게 됨
    def printer(msg):
      print(msg)
    printer("Hi")
    
    # 결과:
    # ******************************
    # Hi
    # ******************************
  • 중첩하여 사용 가능
    picture 8

  • 데코레이터에 변수 부여 가능
    picture 9
    exponent : 2
    f(*args) : raise_two(n)




728x90
728x90