[ Python Object Oriented Programming ]
객체 지향 프로그래밍
객체 : 실생활에서 일종의 물건
속성( Attribute )과 행동( Action )을 가진다.
OOP는 객체 개념을 프로그램으로 표현. 속성은 변수( Variable ), 행동은 함수( Method )으로 표현한다.
파이썬 역시 객체 지향 프로그래밍 언어이다.
OOP는 클래스( class )와 실제 구현체인 인스턴스( instance )로 나눔.
ex) 붕어빵틀 - class, 붕어빵 - instance
class와 instance
1. class 선언하기
class [ class 이름 ]( object ) :
상속받는 객체명
Attribute 추가는 __init__, self와 함께 써줘야한다.
__init__ | self |
객체 초기화 예약 함수 | 생성된 instance 객체 자신 |
* __는 특수한 예약 함수나 변수 그리고 함수명 변경( 맨글링 )으로 사용한다.
ex) __main__, __add__, __str__, __eq__
2. instance 생성하기
# Object 이름 선언과 함께 초기값 입력하기
객체명 = [ class 이름 ]( __init__ 함수 interface / 초기값 )
class SoccerPlayer(object) :
# 객체에 속성 정보를 넣어주기
def __init__(self, name, position, back_number):
self.name = name
self.position = position
self.back_number = back_number
# print문을 실행했을 때 자동으로 호출되는 함수
def __str__(self):
return f"이번에 출전하는 선수는 {self.back_number}번 {self.position} {self.name}선수입니다!"
def __add__(self, other):
return self.name + other.name
# 생성하는 방식은 똑같지만 모두 서로 다른 객체이다.
player1 = SoccerPlayer("2CHAECHAE", "FW", 7)
player2 = SoccerPlayer("2MONMON", "WF", 13)
print(player1) # 이번에 출전하는 선수는 7번 FW 2CHAECHAE선수입니다!
OOP 예제
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())
my_notebook = NoteBook("2CHAECHAE 강의 노트")
day1_note = Note("파이썬 기초 문법")
day2_note = Note("객체 지향 프로그래밍")
my_notebook.add_note(day1_note)
my_notebook.add_note(day2_note,100)
print(my_notebook.notes[100]) # 각 페이지에 있는 content 확인하기
my_notebook.notes[2] = Note("알고리즘")
print(my_notebook.notes[2])
[ OOP 특성 ]
상속( Inheritance )
부모 클래스로부터 속성과 Methon를 물려받는 자식 클래스를 생성하는 것
자식 클래스의 Object에 상속해주는 부모클래스의 이름을 넣어주면 된다.
# 부모 클래스
class Person(object) :
def __init__(self, name, age):
self.name = name
self.age = age
# 자식 클래스
class Korean(Person) :
pass
person1 = Korean("2CHAECHAE", 24)
print(person1.name)
super() : 자기 자신의 부모 클래스
super라는 키워드를 사용해서 부모 클래스가 가지고 있는 속성과 함수를 가져와 사용할 수 있다.
class Person(object) :
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
def about_me(self) :
print(f"이름 : {self.name}, 나이 : {self.age}")
def __str__(self):
return f"이름 : {self.name}, 나이 : {self.age}"
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(f"급여 : {self.salary}, 입사일 : {self.hire_date}")
person1 = Person("2CHAECHAE", 24, "Female")
person1.about_me() # 이름 : 2CHAECHAE, 나이 : 24
person2 = Employee("2MONMON", 24, "Male", 500000, "2021-01-24")
person2.about_me() # 이름 : 2MONMON, 나이 : 24, 급여 : 500000, 입사일 : 2021-01-24
다형성( Polymorphism )
같은 이름의 메소드의 내부 로직을 다르게 작성
개념적으로 같은 기능을 하지만 구현을 다르게 해야할 경우를 다형성이라 한다.
상속을 받을 때 같은 코드지만 다른 기능을 하도록 만들 수 있다.
같은 기능을 할 경우에 다른 함수 명을 사용할 필요 없이 각각의 목적에 맞게 내부 구현만 다르게 하고
같은 이름을 사용한다.
class Animal:
def __init__(self, name):
self.name = name
def talk(self): # 추상메소드
raise NotImplementedError("Subclss must implement abstract method")
class Cat(Animal):
def talk(self):
return 'I\'m a cat!'
class Dog(Animal):
def talk(self):
return 'I\'m a dog!'
# 클래스 인스턴스 생성
animals = [Cat('호야'), Cat('밍키'), Dog('초코')]
for animal in animals :
print(animal.name + ': ' + animal.talk())
가시성( Visibility )
누구나 객체 안에 모든 변수를 볼 필요는 없다.
즉, 우리의 Attribute나 Method를 누구나 쉽게 접근할 수 있는 것을 막아놓는 것을 소스를 보호해
가시성을 조절한다라고 한다.
개념적으로 정보를 나누고 분리를 해야지만 코딩을 조금 더 수월하게 할 수 있다.
* 캡슐화( Encapsulation )
class를 설계할 때 클래스 간섭 / 정보 공유를 최소화하여 인터페이스만 알면 내 코드에 접근할 수 있게 해주는 것
변수를 private로 선언하기 위해서는 변수 명 앞에 '__'를 써주면 된다.
def __init__(self):
self.__items = []
# private 변수로 선언 -> 타객체가 접근을 못하게 함.
private로 선언해주면 items 변수는 외부에서 접근이 되지 않는다.
items 변수를 사용하기 위해서는 접근을 허용해야한다.
접근을 허용하기 위해 @property decorator를 사용해서 숨겨진 변수를 반환해줘야한다.
# items 변수를 사용하기 위해서는 접근을 허용해야한다.
# property decorator : 숨겨진 변수를 반환해준다.
@property
def items(self):
return self.__items
# property decorator로 함수를 변수처럼 호출
items = my_inventory.items
class Product(object) :
pass
class Inventory(object) :
def __init__(self):
self.__items = [] # private 변수로 선언 -> 타객체가 접근을 못하게 한다.
# items 변수를 사용하기 위해서는 접근을 허용해야한다.
# property decorator : 숨겨진 변수를 반환해준다.
@property
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_itmes(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_itmes()) # 2
items = my_inventory.items # property decorator로 함수를 변수처럼 호출
items.append(Product)
print(my_inventory.get_number_of_itmes()) # 3
데코레이터( decorator )
1. First-class objects : 일등 함수 또는 일급 객체
변수나 데이터 구조에 할당이 가능한 객체
파라미터로 전달이 가능 + 리턴값으로 사용
파이썬의 함수는 일급 함수
def square(x) :
return x * x
f = square # 함수를 변수로 사용
f(5)
def formula(method, argument_list): # 함수를 파라미터로 사용
return [method(value) for value in argument_list]
2. inner function : 함수 내에 또 다른 함수가 존재
def print_msg(msg):
def printer():
print(msg)
printer()
print_msg("Hello World!")
# closure : inner function을 return 값으로 반환
another = print_msg("Hello World!")
another()
파이썬은 일급 객체이기 때문에 함수 자체가 리턴이 가능하고 이런 것을 'closure'라 한다.
def tag_func(tag,text):
text = text
tag = tag
def inner_func():
return '<{0}>{1}<{0}>'.format(tag,text)
return inner_func
h1_func = tag_func('tltle', "Python OPP")
p_func = tag_func('p', "Data Engineer")
print(h1_func())
print(p_func())
3. decorator : 복잡한 closure 함수를 간단하게 만들어준다.
@를 사용해 @클래스명을 써주면 데코레이터 밑에 선언된 함수가 데코레이터로 지정된 클래스의 인자값으로 들어간다.
def star(func) :
def inner(*args, **kwargs):
print(args[1] * 30)
func(*args, **kwargs)
print(args[1] * 30)
return inner
@star
# @star라고 써주면 printer 함수가 star 함수의 파라미터인 func에 인자로 들어간다.
def printer(msg, mark):
print(msg)
printer("Hello", "☆")
def generate_power(exponent): # exponent에는 데코레이터에서 선언한 인자값(2)이 들어감
def wrapper(f): # f에 raise_two 함수가 들어감
def inner(*args): # inner 함수의 인자로는 raise_two 함수의 파라미터 값(n)이 들어감
result = f(*args) # result = 49
return exponent ** result # 2^49
return inner
return wrapper
@generate_power(2)
def raise_two(n):
return n ** 2
print(raise_two(7))
'Python > 네이버 부스트코스 AI BASIC 코칭스터디' 카테고리의 다른 글
[ AI 코칭스터디 ] 2주차 학습 ( Module and Project ) (0) | 2022.01.25 |
---|---|
[ AI 코칭스터디 ] 1주차 학습 ( Python Data Structure ) (0) | 2022.01.21 |
[ AI 코칭스터디 ] 1주차 학습 ( String and advanced function concept ) (0) | 2022.01.21 |
[ AI 코칭스터디 ] 1주차 학습 ( Conditionals and Loops ) (0) | 2022.01.19 |
[ AI 코칭스터디 ] 1주차 학습 ( Function and Console I/O ) (0) | 2022.01.18 |