이 자료는 네이버 부스트 코스에서 제공하는 자료로 만들어졌습니다.
파이썬을 개발하는 방법으로 만들어 놓은 코드를 재사용 하는 방법이 있다.
이러한 방법이 클래스와 객체이다.
- 객체 지향 언어의 이해 -
만약에 수강 신청 프로그램을 작성해야한다 어떻게 해여할까?
①수강 신청이 시작부터 끝까지 순서대로 작성
②수강 신청관련 주체들(교수, 학생, 관리자) 의 행동(수강신청, 과목입력)과
데이터(수강과목, 강의과목) 들을 중심으로 프로그램 작성 후 연결
두 가지 모두 가능 최근엔 ②번 방식이 주류 이러한 기법을 객체 지향 프로그램 이라 한다.
그럼 이제 직접 구현해보자
-축구선수정보를Class로구현하기
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
클래스는 아래와 같은 구성을 가진다.
만약에 object는 설정하지 않는다면 py3에서는 자연스럽게 설정을 해주게 된다.
여기서 __init__이라는 예약함수가 있는데 이것의 역할은
속성에 관한 정보를 저장할 때는 __init__이라는 것에 저장을 한다.
그리고 이 함수는 객체를 초기화 하는 함수이다. self 라는 것으로 받는 데 이것은 객체 자기 자신을 나타낸다.
추가적으로 __ 는 특수한 예약함수나 변수 그리고 함수명 변경(맨글링)으로 사용한다.
이제 method 를 구현해보자
여기서 반드시 self를 사용해야하는 이유는 객체를 구분해주기 위해서이다.
저기 self 의 자리에는 각자의 객체의 이름이 들어온다.
만약에 객체의 이름이 abc라고한다면 abc.back_number 이런 식으로 사용된다.
초기 값을 입력하고 사용하면 된다.
그럼 여기서 기억해야 할게 self는 생성된 instance 자기 자신을 이야기한다. 위의 객체 instance는 jinhyun이다. 코드 안에서는 self 자리를 차지하게 된다.
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
jinhyun = SoccerPlayer("Jinhyun", "MF", 10)
print("현재 선수의 등번호는 :", jinhyun.back_number)
jinhyun.change_back_number(5)
print("현재 선수의 등번호는 :", jinhyun.back_number)
아래와 같은 예시가 있다.
- 객체 지향 언어의 특징 실제 세상을 모델링
필요한 것들
- 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), "살 입니다.")
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," 입니다.")
위와 같은 상속이라는 구조인데 object에 부모 클래스의 이름을 적게 된다면 이걸 상속이라고 한다.
이러한 상속은 부모의 속성을 그대로 사용하게 된다.
따라서 코드를 작성하게 된다면 적어줘야한다.
또한 상속을 사용할 때 super() 이라는 것을 __init__ 에 사용 해야하는 데 부모 클래스가 가지고 있는 클래스의 속성을 가져올 수 있다. 또한 부모 클래스의 함수를 가져와서 사용을 할 수도 있다.
- Polymorphism 다형성
함수 명은 같으나 세부적인 구현이 다른 경우에 다형성을 사용한다. 다만 파이썬의 경우에는 약간 어려운 경우가 있다.
이러한 다형성은 위의 예시와 같이 Animal 이라는 클래스가 존재하며 아래의 두개의 클래스 cat과 Dog가 존재한다.
하나의 클래스가 존재하고 아래의 sub 클래스들이 다른 기능을 하게 된다.
내부 구현만 다르고 이름은 동일하게 사용한다. talk()라는 함수는 동일하게 사용하지만 내부의 구현은 다르다.
- Visivility 가시성
만든 객체의 정보를 볼수 있는 레벨을 조절하는 것이 가시성이다.
그럼 다음과 같은 예시를 보자
- Product 객체를 Inventory 객체에 추가
- Inventory에는 오직 Product 객체만 들어감
- Inventory에 Product가 몇 개인지 확인이 필요
- Inventory에 Product items는 직접 접근이 불가
class Product(object):
pass
class Inventory(object):
def __init__(self):
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())
print(my_inventory.__items)
my_inventory.add_new_item(object)
여기서 __ 두개를 사용하면 private 변수로 타 객체가 접근을 하지 못한다.
위의 코드에서 print(my_inventory.__items) 는 접근이 불가능 하다.
다음 예시로는 접근을 가능하게 해주는 방법이다.
class Inventory(object):
def __init__(self):
self.__items = []
@property
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())
items = my_inventory.items
items.append(Product())
print(my_inventory.get_number_of_items())
@ 라는 데코레이터를 property와 함께 사용 해주는 것이다.
이러한 방식은 외부에서는 접근이 불가능하나 내부에서는 접근이 가능하여 반환이 가능하게 해준다.
__items 로 하면 접근이 불가능하지만 기존의 방법인 items 를 사용하면 접근이 가능하다.
- decorate
우리는 일급 객체 inner function, decorator 라는 것을 배우게 될 것이다.
함수를 우리는 변수로도 할당 가능한 것을 말한다. 이러한 것에는 map 함수를 볼 수 있다.
def square(x):
return x * x
def cube(x):
return x*x*x
def formula(method, argument_list):
return [method(value) for value in argument_list]
내부의 함수를 따로 만드는 것도 할 수 있다.
이러한 방식으로 사용을 하게 된다면 다양한 방식으로 함수가 사용될 수 있다.
python의 특성상 함수를 변수로 사용할 수 있기 때문이다.
java 에서 많이 사용되는 방식이라한다.
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('title', "This is Python Class")
p_func = tag_func('p', "Data Academy")
데코레이터와 함께 사용하면 @star라고 할당하면 위로 들어가서 사용이 된다
위의 예시로는 printer 라는 함수가 선언되면 위의 star함수로 들어가게 된다.
위의 방법도 가능한데 데코레이터로 percent를 우선 해주게 된후 다음으로 star를 해주면 출력이 된다.
더 복잡하게는 exponent를 이용해 2라는 값을 넣어주면 위의 함수는
아래와 같은 구조로 돌아가게 된다. 하하 어렵다 ㅋㅋ
근데 여기서 궁금증 *arg 는 정해지지 않은 수의 파라미터 값을 받아 들이는 건데 왜? 저기서 사용되고 inner에서 받아 오는지 모르겠다 나중에 질문 꼭!
'AI > python AI' 카테고리의 다른 글
python - File / Exception / Log Handling (0) | 2022.06.01 |
---|---|
python - Module and Project (0) | 2022.06.01 |
python - function passing arguments (0) | 2022.05.30 |
python - iterable object & generator (0) | 2022.05.30 |
python - lambda & map & reduce (0) | 2022.05.30 |