파이썬 기초 문법 3

Andrew·2021년 1월 21일
1
post-custom-banner

[Contents]

  1. Python Object Oriented Programming
  2. Module and Project

[Python Object Oriented Programming]

  • 객체 지향 프로그래밍 언어, Object Oriented Programming(OOP)에 대해서 배운다.
  • OOP는 프로그래밍 언어를 배우는 데 있어서 매우 중요한 개념이다.
  • 파이썬 자체도 OOP 형태로 구성되어 있기도 하지만, 파이썬 나오기 전에 대세 언어들이였던 자바, C++, C# 같은 언어들이 모두 OOP 기반의 언어들이다.
  • OOP를 배우는 것은 이전에 우리가 if 문이나 고난이도 프로그래밍을 위한 길로 생각하고 이번 챕터를 공부해보자.
  • 클래스와 객체 (객체 지향 언어의 이해)

    • Object-Oriented Programming, OOP
    • 객체 : 실생활에서 일종의 물건
      • 속성(Attribute)와 행동(Action)을 가짐
    • OOP는 이러한 객체 개념을 프로그램으로 표현
      • 속성은 변수(variable), 행동은 함수(method)로 표현됨
    • 파이썬 역시 객체 지향 프로그램 언어
    • 인공지능 축구 프로그램을 작성한다고 가정
    객체 종류ActionAttribute
    팀, 선수, 심판, 공선수 - 공을 차다, 패스하다선수 - 선수 이름, 포지션, 소속팀
    심판 - 휘슬을 불다, 경고를 주다팀 - 팀 이름, 팀 연고지, 팀 소속 선수
    • OOP는 설계도에 해당하는 클래스(class)와 실제 구현체인 인스턴스(instance)로 나눔

objects in python

  • class 선언하기
#class예약어 class이름  상속받는 객체명
class SoccerPlayer(object):
  • Attribute 추가하기
    • Attribute 추가는 __init__, self 와 함께!
    • __init__객체 초기화 예약함수
class SoccerPlayer(object):
    def __init__(self, name, position, back_number):
        self.name = name
        self.position = position
        self.back_number = back_number
  • 파이썬에서 __ 의미

    • __ 는 특수한 예약 함수나 변수 그리고 함수명 변경(맨글링)으로 사용
    • 예: __main__, __add__, __str__, __eq__
    • __str__ : print()를 사용했을때 실행되는 함수
  • method 구현하기

    • method(Action) 추가는 기존 함수와 같으나, 반드시 self를 추가해야만 class 함수로 인정됨
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
  • objects(instance) 사용하기
    • Object 이름 선언과 함께 초기값 입력하기
  • what's self?
    • 생성된 instance 자신
tmp = SoccerPlayer('Jinhyun', 'MF', 10) 
# tmp는 class코드안에서 self 라고 불리고 코드 밖에서는 자기 변수명 tmp로 불린다. 

OOP Implementation Example

  • 구현 가능한 OOP 만들기 - 노트북
    • Note를 정리하는 프로그램
    • 사용자는 Note에 뭔가를 적을 수 있다.
    • Note에는 Content가 있고, 내용을 제거할 수 있다.
    • 두 개의 노트북을 하나로 만들 수 있다.
    • Note는 Notebook에 삽입된다.
    • Notebook은 Note가 삽입 될 때 페이지를 생성하며, 최고 300페이지까지 저장 가능하다
    • 300 페이지가 엄으면 더 이상 노트를 삽입하지 못한다.
    Class : NotebookClass : Notebook
    methodvariablemethodvariable
    add_notetitlewrite_contentcontent
    remove_notepage_numberremove_all
    get_number_of_pages
# Note class
class Note(object):
    def __init__(self, content = None): # variable = content
         self.content = content
     
     def write_content(self, content): # write_content
         self.content = content
     
     def remove_all(self):        # remove_all
         self.content = ""
     
     def __add__(self, other):
         return self.content + other.content
     
     def __str__(self):
         return self.content
       
# NoteBook class
class NoteBook(object):  
    def __init__(self, title):  # variables = title, page_number, notes
        self.title = title
        self.page_number = 1
        self.notes = {}

    def add_note(self, note, page = 0):  # add_note
        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):    # remove_note
        if page_number in self.notes.keys():
            return self.notes.pop(page_number)
        else:
            print("해당 페이지는 존재하지 않습니다")
            
    def get_number_of_pages(self):   # get_number_of_pages
        return len(self.notes.keys())

OOP Characteristics

  • 객체 지향 언어의 특징 - 실제 세상을 모델링하기 위해 필요한 것 들
    • inheritance (상속)
    • polymorphism (다형성)
    • visibility
  • 상속 (inheritance)
    • 부모클래스로 부터 속성과 Method를 물려받은 자식 클래스를 생성하는 것
# 부모 클래스
class Person(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age
        self.gender = gender 
    
    def about_me(self): # Method 선언
        return '저의 이름은.' self.name, '이구요, 제 나이는 ', str(self.age), '살 입니다.')    
    def __str__(self):
        return '저의 이름은 {0} 입니다. 나이는 {1} 입니다". format(self.name, self.age)
        
class Employee(Person): # 부모 클래스 Person으로 부터 상속
    def __init__(self, name, age, gender, salary, hire_date):
        super().__init__(name, age, gender) # 부모객체 사용. super는 자기자신의 부모클래스. 즉, Person의 속성을 불러온다. 
        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, " 입니다.")
  • Polymorphism (다형성)
    • 같은 이름 메소드의 내부 로직을 다르게 작성
    • Dynamic Typing 특성으로 인해 파이썬에서는 같은 부모클래스의 상속에서 주로 발생함
    • 중요한 OOP의 개념 그러나 너무 깊이 알 필요X
  • Visibility (가시성)
    • 객체의 정보를 볼 수 있는 레벨을 조절하는 것
    • 누구나 객체 안에 모든 변수를 볼 필요가 없음
      1) 객체를 사용하는 사용자가 임의로 정보 수정
      2) 필요 없는 정보에는 접근 할 필요가 없음
      3) 만약 제품으로 판매한다면? 소스의 보호
    • Encapsulation
      • 캡슐화 또는 정보 은닉(Information Hiding)
      • Class를 설계할 때, 클래스 간 간섭/정보공유의 최소화
      • 심판 클래스가 축구선수 클래스 가족 정보를 알아야 하나?
      • 캡슐을 던지듯, 인터페이스만 알아서 써야함
    • Visibility Example 1
      • Product 객체를 Inventory 객체에 추가
      • Inventory에는 오직 Product 객체만 들어감
      • Inventory에 Product가 몇 개인지 확인이 필요
      • Inventory에 Product items는 직접 접근이 불가
class Product(object):
    pass

class Inventory(object):
    def __init__(self):
        self.__items = [] # __ = Private 변수로 선언! 타객체가 접근 못함 (items 변수는 외부에서 접근을 하지 못함)
  
    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)
  • Visibility Example 2
    • Product 객체를 Inventory 객체에 추가
    • Inventory에는 오직 product 객체만 들어감
    • Inventory에 Product가 몇 개인지 확인이 필요
    • Inventory에 Product items 접근 허용
class Inventory(object):
	def __init__(self):
		self.__items = []
	
    # items를 외부에서는 접근불가. 내부에서는 접근이 가능해지면서 반환 가능
	@property # property decorator 숨겨진 변수를 반환하게 해줌
	def items(self):
		return self.__items

    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())
print(my_inventory.get_number_of_items())

items = my_inventory.items # property decorator로 함수를 변수처럼 호출
items.append(Product())
print(my_inventory.get_number_of_items())

Decorate

이해하기 위한 개념들

  • first-class objects
    • 일등함수 또는 일급 객체
    • 변수나 데이터 구조에 할당이 가능한 객체
    • parameter로 전달이 가능 + 리턴 값으로 사용
    • 파이썬의 함수는 일급함수
def square(x):
	return x*x

f = square  # 함수를 변수로 사용가능
f(5) 
list(map(f, [5,2])) # parameter로 전달이 가능       
  • inner function
    • 함수 내에 또 다른 함수가 존재
    • closures : inner function을 return값으로 반환. 함수자체를 return값으로 반환.
def print_msg(msg):
	def printer(): # 함수 내에 또 다른 함수 존재
    	print(msg)
    return printer # printer 함수 자체를 return 받는다 (closures)
another = print_msg('Hello, Python')
another() # printer 함수 그 자체다.
  • decorator function
    • 복잡한 클로져 함수를 간단하게!
## example 1)
def star(func):
    def inner(*args, **kwargs):
        print("*" * 30)
        func(*args, **kwargs)
        print("*" * 30)
    return inner

def percent(func):
    def inner(*args, **kwargs):
        print("%" * 30)
        func(*args, **kwargs)
        print("%" * 30)
    return inner

@star
@percent
def printer(msg): 
    print(msg)
printer("Hello")
# 리턴값 = 
# ******************************
# %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# Hello
# %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# ******************************

# 위에 데코레이터는 아래처럼 동작한다
def star(func):
    def inner(*args, **kwargs):
        print("*" * 30)
        func(*args, **kwargs)
        print("*" * 30)
    return inner

def percent(func):
    def inner(*args, **kwargs):
        print("%" * 30)
        func(*args, **kwargs)
        print("%" * 30)
    return inner


def printer(msg): 
    print(msg)
    
printer = star(percent(printer))
printer("Hello")


## example 2)
def generate_power(exponent):
    def wrapper(f):
        def inner(*args):
            result = f(*args)
            return exponent**result
        return inner
    return wrapper
@generate_power(2)
def raise_two(n):
    return n**2
print(raise_two(7)) # 562949953421312

# 위에 데코레이터는 아래와 같이 동작
def generate_power(exponent):
    def wrapper(f):
        def inner(*args):
            result = f(*args)
            return exponent**result
        return inner
    return wrapper

def raise_two(n):
    return n**2

raise_two = generate_power(2)(raise_two)
raise_two(7) # 562949953421312

[Module and Project]

  • 파이썬 프로젝트의 기본이 되는 모듈과 패키지, 그리고 프로젝트의 개념에 대해서 배운다.

모듈과 프로젝트

  • 모듈 overview

    • 어떤 대상의 부분 혹은 조각
    • 프로그램에서는 작은 프로그램 조각들, 모듈들을 모아서 하나의 큰 프로그램을 개발함
    • 프로그램을 모듈화 시키면 다른 프로그램이 사용하기 쉬움
      • 예: 카카오톡 게임을 위한 카카오톡 접속 모듈
  • 모듈 만들기

    • 파이썬의 Module == py 파일을 의미

    • 같은 폴더에 Module에 해당하는 .py파일과 사용하는 .py을 저장한 후

    • import 문을 사용해서 module을 호출

  • 패키지

    • 모듈을 모아놓은 단위, 하나의 프로그램
    • 하나의 대형 프로젝트를 만드는 코드의 묶음
    • 다양한 모듈들의 합, 폴더로 연결됨
    • __init__, __main__ 등 키워드 파일명이 사용됨
    • 다양한 오픈 소스들이 모두 패키지로 관리됨
  • 패키지 만들기

    • 폴더별로 __init__.py 구성하기
      • 현재 폴더가 패키지임을 알리는 초기화 스크립트
      • 없을 경우 패키지로 간주하지 않음 (3.3+ 부터는 X)
      • 하위 풀더와 py 파일(모듈)을 모두 포함함
      • import 와 __all__ keywoard 사용

오픈소스 라이브러리 사용하기

  • 두 개의 프로젝트 웹과 데이터 분석 패키지는 둘다 설치?

    • 둘이 같이 한번에 설치 하다보면 서로 충돌이 날 때가 있다
    • 충돌을 방지하기 위해서 가상환경을 만든다.
  • 가상환경 설정하기 (Virtual Environment)

    • 프로젝트 진행 시 필요한 패키지만 설치하는 환경
    • 기본 인터프리터 + 프로젝트 종류별 패키지 설치
      • 예: 웹 프로젝트, 데이터 분석 프로젝트 -> 각각 패키지 관리할 수 있는 기능
    • 다양한 패키지 관리 두구를 사용함
    • 대표적인 도구 virtualenv 와 conda 가 있음
    virtualenv + pipconda
    가장 대표 적인 가상환경 관리 도구사용 가상환경 도구. miniconda 기본 도구
    레퍼런스 + 패키지 개수설치의 용이성. Windows에서 장점
  • conda 가상환경

    • 가상환경 만들기
      • conda create -n my_project python = 3.8
    • 가상환경 호출
      • conda activate my_project
    • 가상환경 해제
      • conda deactivate
  • 패키지 설치

    • Windows에서는 conda
    • linux, mac에서는 conda or pip
  • tqdm 패키지

    • loop이 돌때 어느정도 시간이 걸리고 앞으로 어느정도 시간이 남았는지 계산해서 보여준다.
    • 프로그램을 돌릴때 내가 지금 현재 어느 상태에 있는지 확인하는 것이 중요하다!! 특히 대용량 데이터를 돌릴때는 더더욱! tqdm 패키지 사용!!
profile
아기개발자
post-custom-banner

0개의 댓글