9장. 객체와 클래스 (가장 중요한 단원)
PYTHON2017. 9. 10. 00:43
ㅁ■ 객체와 클래스 (가장 중요한 단원)
- 9장 목차
- 객체와 클래스
- 클래스의 정의
- __init__() 메소드를 이용한 초기화작ㅇ업
- self에 대한 이해
- 정적 메소드와 클래스 메소드
- 클래스 내부에게만 ㅇ려려있는 프라이빗 멤버
- 상속
- 오버라이딩
- __call()__ 메소드
- for문으로 순회를 할 히 있는 객체 만들기
- 추상기반 클래스
■ 9.1 객체와 클래스
객체(object) = 속성(attribute) + 기능
자동차 ↑ ↑
자동차 색깔 전진, 후진,좌회전,우회전
바퀴의 크기
코드로 구현을 하면 ?
객체 = 변수 + 함수
예제 :
class Car
def __init__(self):
self.color =0xFF0000 # 자동차의 색
self.whell_size = 16
self.displacement = 2000 # 엔진 배기량
def forward(self) : # 전진하는 기능
pass
def backward(self) : # 후진하는 기능
pass
def turn_right(self): # 우회전 하는 기능
pass
def turn_left(self): #좌회전 하는 기능
pass
if __name__ == '__main__' : # 메인 모듈일때만 아래의 스크립트를 실행해라
my_car = Car() # 클래스를 가지고 인스턴스화 하는 코드
# Car() 클래스로 my_car라는 객체를 생성했다.
print('0x{:02X}'.format(my_car.color))
print(my_car.whell_size))
print(my_car.displacement)
my_car.forward() # my_car 의 메소드(기능) 를 호출
my_car.backward()
my_car.turn_left()
my_car.turn_right()
■ 9.2. 클래스의 정의
클래스(자료형) ----> 객체(변수)
위의 클래스는 자료형이고 아직 객체가 되지 않았다
붕어빵 틀 붕어빵 (인스턴스, 실체라고 얘기함)
(속성: 붕어빵 색
붕어빵 앙금(팥, 슈크림)
기능: 왼쪽으로 가라 오른쪽으로 가라
my_car = Car() # Car() 클래스에 의해서 my_car라는 객체가 생성됨 인스턴스화 됨
객체 = 속성 + 기능
(변수) (함수)
- 코드 설명 :
def __init__(self):
1. __init__ ? 객체가 생성될때 호출되는 메소드로서 객체의 초기화를 담당한다
2.self ? 메소드의 첫번째 매개변수로 객체 자신임을 나타냄
3.my_car = Car() ? car() 생성자는 car 클래스의 인스턴스를 생성하여 반환한다.
↑ ↑
인스턴스 생성자
(실체) (설계도)
■ 9.3 __init__() 메소드를 이용한 초기화
클래스의 생성자가 호출이되면 내부적으로 두개의 메소드가 호출된다.
- __new__() : 클래스의 인스턴스를 만드는 역할 ( 내부적으로 자동으로 호출된다.)
- __init__() : 객체가 생성될 대 객체를 초기화하는 역할
- 만약 __init__() 메소드를 클래스 생성할 때 지정안하며 ㄴ어떻게 되는지 테스트
1.__init__() 메소드를 지정 안 했을때
class ClassVar:
text_list = [] # 클래스의 정의 싷점에서 바로 메모리에 할당됨
def add(self,text):
self.text_list.append(text)
def print_list(self):
print(self.text_list)
if __name__ == '__main__':
a = ClassVar()
ㅁ■ 객체와 클래스 (가장 중요한 단원)
- 9장 목차
- 객체와 클래스
- 클래스의 정의
- __init__() 메소드를 이용한 초기화작ㅇ업
- self에 대한 이해
- 정적 메소드와 클래스 메소드
- 클래스 내부에게만 ㅇ려려있는 프라이빗 멤버
- 상속
- 오버라이딩
- __call()__ 메소드
- for문으로 순회를 할 히 있는 객체 만들기
- 추상기반 클래스
9.4 self 에 대한 이해
" 클래스에서 사용하는 최도 매개변수인데 self는 자기 자신을 가리킨다"
9.5 정적 메소드와 클래스 메소드
1.인스턴스 메소드 : 로봇의 팔이 잘 작동하는지 로봇을 만들어노혹 작동해 보면 확이하는 메소드
2.클래스(정적) 메소드 : 로봇의 팔이 잘 작동하느니즈이 확인을 로봇을 만들지 않고 어떻게 하면 로봇팔이 움진인다는 프로그램 코드를 실행히셬 확인하는 메소드
class Calculator:
@staticmethod
def plus(a, b):
return a+b
@staticmethod
def minus(a, b):
return a-b
@staticmethod
def multiply(a, b):
return a*b
@staticmethod
def divide(a, b):
return a/b
if __name__ == '__main__':
print("{0} + {1} = {2}".format(7, 4, Calculator.plus(7, 4)))
print("{0} - {1} = {2}".format(7, 4, Calculator.minus(7, 4)))
print("{0} * {1} = {2}".format(7, 4, Calculator.multiply(7, 4)))
def divide(a, b):
return a/b
if __name__ == '__main__':
print("{0} + {1} = {2}".format(7, 4, Calculator.plus(7, 4)))
print("{0} - {1} = {2}".format(7, 4, Calculator.minus(7, 4)))
print("{0} * {1} = {2}".format(7, 4, Calculator.multiply(7, 4)))
print("{0} / {1} = {2}".format(7, 4, Calculator.divide(7, 4)))
■ 어제 배웠던 내용 복습
1. 클래스 와 객체
(붕어빵틀) (붕어빵)
객체의 구성요소 2가지
1. 속성(변수)
2. 기능(함수)
class gorilla class pingpong
속성: 고릴라 색깔 공과 판의 색깔, 위치
기능: 고릴라 기능 좌로 이동, 우로 이동
gorilla() = gorilla() -----> 생성자 pingpoing = pingpoing()
2. 객체를 초기화 해주기 위해서 필요한 키워드, 메소드?
self, __init__
■ 9.6 클래스 내부에게만 열려있는 프라이빗 멤버(pg200)
* 파이썬에서 사용하는 멤버 2가지
1. public member : 클래스 안에서든 밖에서든 접근 가능 한 멤버
예: 접두사가 두개의 밑줄이고 접미사도 두개의 밑줄이면
__number__
2. private member : 클래스 안에서만 접근 가능한 멤버
클래스의 사생활을 지켜줘야할 때 요긴하게 사용됨
예: 접두사가 두개의 밑줄이고 접미사는 없거나 하나의 밑줄
__number
__number_
6. 클래스 내부에게만 열려있는 프라이빗 멤버
○ 파이썬에서 사용하는 멤버 2가지
i. public member - 클래스 안에서든 밖에서든 접근 가능한 멤버
□ 접두사가 두개의 밑줄이고 접미사도 두개의 밑줄이면 퍼블릭 멤버, __number__
ii. private member - 클래스 안에서만 접근 가능한 멤버, 클래스의 사생활을 지켜줘야할 때 요긴함
□ 접두사가 두개의 밑줄이고 접미사는 없거나 하나의 밑줄, __number_ / __number
• 예제 - 퍼블릭 멤버로 사용했을 경우
class yourclass:
pass
class myclass:
def __init__(self):
self.message = "Hello"
def some_method(self):
print(self.message)
obj = myclass()
obj.some_method() #메소드를 실행했기 때문에 출력이 된 것, 객체명.기능 --> 실행
print(obj.message) #따로 message라는 변수의 내용을 출력, print해서 본 것
• 예제 - 프라이빗 멤버로 사용했을 경우
class yourclass:
pass
class myclass:
def __init__(self):
self.message = "Hello"
self.__private = "private"
def some_method(self):
print(self.message)
print(self.__private)
obj = myclass()
obj.some_method()
print(obj.message)
print(obj.__private) #프라이빗이라서 에러가 난다.
9.7 상속
• 상속 : 클래스들끼리 유산(기능) 을 물려주는 것
클래스 ---------------------------------> 클래스
부모 유산(기능) 자식 으로 물려주는 것
• 상속을 받게 되면 자식 클래스에 부모 기능을 코딩하지 않아도 됨.
학습시키는 클래스(짝꿍) --------------------------> 나는 핑퐁게임 클래스만 만들고 나머지는 상속 받아서 사용
• 예제1
class father :
def base_method(self) :
클래스 부모 ------------------- 클래스 자식 상속
상속을 받게되면 부모의 기능을 굳이 자식 클래스에 코딩하지 않아도 된다.
학습 시키는 클래스 (짝꿍) -------------------------> 나는 핑퐁게임 클래스
머신러닝 기능 유산
예제 1 :
class father
def base_mothod(self) :
print("hello")
class child(father):
pass
father = father()
father.base_method()
child = child()
child.base_method()
예제2. __init__ 메소드를 가지고 실행하는데 부모와는 틀리게 자식에message라는 속성이 없어서 상속을 시키고 싶을때?
class father:
def __init__(self):
print("hello~~")
self.message="Good Morning"
class child(father):
def __init__(self):
print("hello~~ I am child")
child = child()
print(child.message) <==========애기는 굿모닝 못하네여
class father:
def __init__(self):
print("hello~~")
self.message="Good Morning"
class child(father):
def __init__(self):
father.__init__(self) # 파이썬은 암묵적인 것을 싫어하고 명시적인것을 좋아한다.
프로그래머가 명시적으로 클래스의 초기화 메소드를 호출해주길 원함
print("hello~~ I am child")
child = child()
print(child.message)
■ super()
child = child()
print(child.message)
super() 는 부모클래스의 객체 역할을 하는 내장 함수.
사실상 super() 함수의 반환값을 상위객체로 지정한다 다른 클래스로 교체되거나 수정되어도 파생클래스가
받는 영향을 최소화 할 수 있다.
class father:
def __init__(self):
print("hello~~")
self.message="Good Morning"
class child(father):
def __init__(self):
#father.__init__(self)
super.__init__()
print("hello~~ I am child")
child = child()
print(child.message)
■ 다중상속
다중 상속이란 두개 이상의 클래스를 상속 받는것을 말한다
이 경우에는 두 클래스의 모든 속성을 물려받게된다
이는 하나의 자식 클래스가 두개 이상의 부모 클래스를 가지는 것이라고 할 수 있다.
father1 father2
↘ ↙
child
예제 1:
class father1:
def func(self):
print("지식")
class father2:
def func(self):
print("지혜")
class child(father1,father2):
def childfunc(self):
father1.func(self)
father2.func(self)
objectchild = child()
objectchild.childfunc()
objectchild.func() # 결과 : 지식 (물려 받은 순서 우선순위 출력 father1 의 지식이 출력된다.)
■ 그런데 둘다 출력하기 싫고 하나만 출력하고 싶어서
grandfather
↙ ↘
father1 father2
↘ ↙
grandchild
예제 :
class grandfather:
def __init__ (self):
print("튼튼한 두팔")
class father1(grandfather):
def __init__ (self):
grandfather.__init__(self)
print("지식")
class father1(grandfather):
def __init__ (self):
grandfather.__init__(self)
print("지혜")
class grandchild(father1, father2):
def __init__(self):
father1.__init__(self)
father2.__init__(self)
print("난 행복해")
grandchild = grandchild()
결과 :
튼튼한 두팔
지식
튼튼한 두팔
지혜
난 행복해
다이아몬드 상속을 받았더니 그만 팔이 4개가 되어부럿당!
문제166. (점심시간 문제) 다시 팔이 2개가 되게 하시오
class grandfather:
def __init__ (self):
print("튼튼한 두팔")
class father1(grandfather):
def __init__ (self):
super().__init__()
print("지식")
class father2(grandfather):
def __init__ (self):
super().__init__()
print("지혜")
class grandchild(father1, father2):
def __init__(self):
super().__init__()
print("난 행복해")
grandchild = grandchild()
6 클래스내부에게만 열려잇느 프라이빗 멤버
7 상속
8 오버라이딩
9 __call()__메소드
10 for 문으로 순회를 하룻 잇는 객체 만들기
11 추상 기반 클래스
9.6 오버라이딩
~ 보다 우선한다는 뜻이다
부모로 부터 상속받은 메소드를 다시 Override(재정의) 하겠다.
예제:
class grandfather:
def __init__(self):
print("튼튼한 두팔")
class father2(grandfather):
def __init__(self):
print("지혜")
father2 = father2()
지혜도 주요지만 건강도 물려받고싶다면
class grandfather:
def __init__(self):
print("튼튼한 두팔")
class father2(grandfather):
def __init__(self):
super().__init__()
print("지혜")
father2 = father2()
■ super() 에 대해서?
1.super()를 이용하면 부모클래스의 멤버에 접근을 할 수 있따.
2.super()를 이용하면 부모 클래스 명이 변경되어도 일일이 코드를 고치는 수고를 줄일 수 있다.
3.super()를 이요함녀 죽음의 다이아몬드 상속을 피할 수 있다.
aa■ 9.6 데코레이터 사용법
데코레이터의 사전적 의미? 꾸미다
데코레이터는 함 수를 꾸며주는 함수
데코레이터는 함수의 능력을 확장 시켜준다.
어떤 동작을 수행하기 전에 @ 로 시작하는 키워드를 사용해서 수행한다.
- 데코레이터의 중요한 2가지 기능
- 1. 함수를 강력하게 해준다.
- 2. 공통적으로 사용하는 코드를 쉽게 관리하기 위해서 사용한다
- 파이썬 함수의 4가지 특징
- 1. 변수에 할당 할 수 있다.
- 2. 다른 함수내에서 정의 될 수 있다.
- 3. 함수의 인자(매개변수)값으로 전달될 수 있다.
- 4. 함수의 반환값이 될 수 있다.
- 함수를 !!! 변수에 할당!!!!
def greet(name):
return "Hello {} ".format(name)
greet_someone = greet # 함수를 변수에 할당
print(greet_someone("scott"))
- 다른 함수내에서 정의 할수 있어!!!!!
def greet(name):
def greet_message():
return 'Hello'
return "{} {}".format(greet_message(),name)
print(greet("scott"))
- 함수의 인자값으로 전달 될 수 있다!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
예:
def greet(name):
return "Hello {}".format(name)
def change_name_greet(func):
name = "king"
return func(name)
print( change_name_greet(greet))
- 함수의 반환값이 될 수 있다.
def greet (name):
return "Hello {}".format(name)
def uppercase (func):
def wrapper(name):
result = func(name)
return result.upper()
return wrapper
new_greet = uppercase(greet) ("scott")
print(new_greet)
print(new_greet("scott"))
문제167. 이름을 입력하고 함수를 실행하면
해당하는 사원들의 직업이 소문자로 출력되는 함수를 생성하시오 !
함수1. 이름을 입력했을때 직업이 출력되는 함수 (find_job)
함수2. 문자를 입력했을때 소문자로 출력하는 함수 (lower_case)
def find_job(name):
import pandas as pd
emp = pd.DataFrame.from_csv("d:/data/emp.csv")
job = emp[['job']][emp['ename'] == name].values[0][0]
return job
def lowercase(func):
def wrapper(name):
result = func(name)
return result.lower()
return wrapper
new_find_job = lowercase(find_job)
print(new_find_job('SCOTT'))
■ 데코레이터 표현법을 보기전에 먼저 데코레이터와 같은
역할을 하는 함수를 생성
class greet(object):
current_user = None
def set_name(self,name): # current_user 라는 변수인 속성은 선언
if name =='admin': #name 에 admin 이라는 문자를 담고
self.current_user = name
else: #admin 이 아니라면 권한이 없다는 에러를
raise Exception("권한이 없네요") #발생시키는 함수
def get_greeting(self,name): #name 이라는 매개변수에 admin 이
if name == 'admin': # 입력이 됬다면
return "Hello {}".format(self.current_user)
#Hello 와 current_user 를 리턴하는
#함수
실행방법:
greet = greet()
greet.set_name('admin')
print(greet.get_greeting('admin'))
'Error cuz of object is not callable'
greet = greet()
greet.set_name('scott')
print(greet.get_greeting('scott')) # scott 은 안되거든?
문제168.어드민만 헬로 출력되게하라
class greet(object): # current_user 라는 변수인 속성을 선언
current_user = None # name에 admin이라는 문자가 들어오면
def set_naem(self,name): #current_user 에 admin 이라는 문자를 담고
if name == 'admin':
self.currnet_user = name
else: #admin이 아니라면 권한이 없다는 에러를 발생시킴
raise Exception("권한이 없네요")
def get_greeting(self,name): # name이라는 매개변수에 admin이 입력되면
if name == 'admin':
return "Hello {}".format(self.current_user)
# Hello와 current_user를 리턴하는 함수
실행방법 :
greet = greet()
greet.set_name('admin')
print(greet.get_greeting('admin') )
위의 코드에서 중복되는 부분 즉 admin이 맞는지 확인하는 공통적인 코드를 하나의 함수로 만들어서 따로 떼어낼 수 있을 것 같다.
def is_admin(user_name):
if user_name != 'admin':
raise Exception("권한이 없다니까요 ")
class greet(object):
current_user = None
def set_name(self,name):
is_admin(name)
self.current_user = name
def get_greeting(self,name):
is_admin(name)
return "Hello {}".format(self.current_user)
greet = greet()
greet.set_name('admin')
print(greet.get_greeting('admin') )
문제169. 이름을 넣어서 함수를 실행하면 해당 사원의 월급이 출력되게 함수를 생성하는데
KING 만 월급을 볼 수 있게 하고 KING이 아닌 다른 사원들은 권한이 없다면서 볼 수 없게 에러가 나게 하시오 !
import pandas as pd
def is_admin(user_name):
if user_name != 'KING' and :
raise Exception("권한이 없다니까요 ")
class find_sal(object):
current_user = None
def set_name(self,name):
is_admin(name)
self.current_user = name
def get_sal(self,name):
is_admin(name)
emp = pd.DataFrame.from_csv("d:/data/emp.csv")
sal= emp[['sal']][emp['ename'] == name].values[0][0]
return sal
find_sal = find_sal ()
find_sal.set_name('KING')
print(find_sal.get_sal('KING') )
문제170.위에 is_admin(name) 이라는 함수를 사용해서 코드가 더 좋아졌다 하지만 데코레이터를 이용하면 함수가 더
좋아진다. 데코레이터를 써서 구현하시오
def is_admin(func):
def wrapper(*arg,**kwargs): # *arg 리스트의 가변 매개변수
# **kwargs 딕셔너리 가변 매개변수
if kwargs.get('name') != 'admin':
raise Exception("권한이 없다니까요 ")
return func(*arg,**kwargs)
return wrapper
class greet(object):
current_user = None
@is_admin
def set_name(self,name):
self.current_user = name
@is_admin
def get_greeting(self,name):
return "Hello {}".format(self.current_user)
greet = greet()
greet.set_name(name='admin')
print(greet.get_greeting(name='admin') )
문제171. 문제169 코드를 데코레이터 함수를 이용해서 더 좋게 개선시키시오
import pandas as pd
def is_admin(func ):
def wrapper(*arg,**kwargs): # *arg 리스트의 가변 매개변수
# **kwargs 딕셔너리 가변 매개변수
if kwargs.get('name') != 'KING' :
raise Exception("권한이 없다니까요 ")
return func(*arg,**kwargs)
if arg[1] == 'SCOTT' :
raise Exception("스콧이당!")
return func(*arg,**kwargs)
return wrapper
class find_sal(object):
current_user = None
@is_admin
def set_name(self,name):
self.current_user = name
def get_sal(self,name):
emp = pd.DataFrame.from_csv("d:/data/emp.csv")
sal= emp[['sal']][emp['ename'] == name].values[0][0]
return sal
find_sal = find_sal ()
find_sal.set_name(name = 'KING')
print(find_sal.get_sal(name = 'KING') )
import pandas as pd
def is_admin(func ):
def wrapper(*arg,**kwargs): # *arg 리스트의 가변 매개변수
# **kwargs 딕셔너리 가변 매개변수
if arg[1] == 'SCOTT' :
raise Exception("스콧이당!")
return func(*arg,**kwargs)
if kwargs.get('name') != 'KING' :
raise Exception("권한이 없다니까요 ")
return func(*arg,**kwargs)
return wrapper
class find_sal(object):
current_user = None
@is_admin
def set_name(self,name):
self.current_user = name
@is_admin
def get_sal(self,name):
emp = pd.DataFrame.from_csv("d:/data/emp.csv")
sal= emp[['sal']][emp['ename'] == name].values[0][0]
return sal
find_sal = find_sal ()
find_sal.set_name(name = 'KING')
print(find_sal.get_sal('SCOTT') )
객체와 클래스 (가장 중요한 단원)
■ 어제 배운내용 복습
1. 클래스 멤버 2가지
-- public member
-- private member
2. 상속
- 상속이 필요한 이유? 코드를 간결하게 하기위해서
객체 지향언어를 제대로 활용하는 방법(object -oriented )
1팀 : 로폿팔 클래스
2팀 : 로봇다리 클래스
3팀 : 로봇 몸체 클래스
4팀 : 로봇 두뇌(인공신경망) 클래스
로봇팔에 버그가 있어 개선하는데 다리까지 영향을 끼친다 안돼!
==> 결국 유지보수 비용을 줄일수 있다.
파이썬 (코어) 개발
파이썬 개발자 중급 400 ~ 600
- 객체 (인스턴스)? 리스트 , 튜플, 딕셔너리 처럼 데이터를 다루기 위한 논리적 집합
↓ ↓
데이터를 어떤 형식으로 저장할 건가? 속성(변수)에 데이터를 넣고
기능(함수)로 데이터를 다루는 역할
3만건의 영어 단어장 ----- 겨울왕국 스크립트 리스트 --->
리스트 리스트 full table scan
(100초)
딕셔너리 딕셔너리 index scan
key:value key:value (1초)
- 클래스란? 변수 + 기능 으로 구성된 논리적 집합 !
인스턴스? 클래스(설계도) 를 실체화 한것
문제172. gun이라는 인스턴스를 생성하기 위해서 gun() 클래스를 생성하시오
gun = gun() # 총 설계도로 총을 실체화 시킴
gun.charge(10) # 총알 10발 충전
gun.shoot(3)
탕
탕
탕
7발 남았습니다.
gun.print() # 현재 총알이 얼마나 남았습니다.
7발 남았습니다.
class gun:
def __init__(self):
self.bu =0
def print(self):
print('{} 발 남았습니다.'.format(self.bu))
def charge(self,n):
self.bu += n
def shoot(self,a):
for i in range(a):
if self.bu > 0 :
self.bu -= 1
print ('탕 !')
elif self.bu == 0 :
print('총알이 없습니다')
break
print(self)
gun = gun() # 총 설계도로 총을 실체화 시킴
gun.charge(10) # 총알 10발 충전
gun.shoot(4)
gun.print()
예제2. 클래스를 사용하는 이유?
class employee(object)
pass
emp_1 = employee()
emp_2 = employee()
예제2. 클래스를 사용하는 이유?
- 딕셔너리를 사용하는 경우
student = {'name': '김인호', 'year':2,'class':3,'student_id':35}
print('{}, {}학년 {}반 {}번'.format(student['name'],student['year'],student['class'],student['student_id']) )
- 클래스를 사용하는 경우
class student(object):
def __init__(self,name,year,class_num,student_id):
self.name = name
self.year = year
self.class_num = class_num
self.student_id = student_id
def introduce_myself(self):
return '{}, {}학년 {}반 {}번'.format(self.name, self.year, self.class_num,self.student_id)
student = student('김인호',2,3,35)
print (student.introduce_myself())
문제173. 위의 student 클래스를 다시 실행하는데 self 빼고해라
TypeError: introduce_myself() takes 0 positional arguments but 1 was given
introduce_myself()라는 메소드는 인자값을 안받게 만들어줘놓고 왜 하나를 줬느냐
인스턴스의 메소드를 호출하면 인스턴스 자기 자신인 self가 첫번째 인자로 자동으로 전달되기 때문이다.
def introduce_ myself(): # <-- self가 없습니다.
파이썬에서는 인스턴스의 메소드를 호출함녀 인스턴스 자기자신인 self가 첫번재 인자로 자동으로 전달되므로
반드시
def introduce_myself(self) # <=== self를 넣어줘야 한다.
문제173. 자기 자신이 인스턴스의 메소드에 인자로 전달된다는 것이 어떤것인지 인스턴스를 통하지 않고
바로 클래스 introduce_myself를 직접 호출해서 확인하시오
class student(object):
def __init__(self,name,year,class_num,student_id):
self.name = name
self.year = year
self.class_num = class_num
self.student_id = student_id
def static introduce_myself(self):
return '{}, {}학년 {}반 {}번'.format(self.name, self.year,
self.class_num,self.student_id)
student1 = student('김인호',2,3,35)
print (student.introduce_myself())
■ self 를 왜 강조하느냐?
파이썬은 객체함수를 나타낼때 무조건 def(self,x,y)
이렇게 self를 첫번째 인자로 넣어야한다.
자바나 c++에서는 this 를 명시 안해도 되나 파이썬은 강제입니다.
■ static method ?
(정적 메소드 )
- self를 매개변수로 받지 않는 메소드
- 여러 인스터스가 공유해서 사용하는 메소드
class gun:
def __init__(self):
self.bu =0
def print(self):
print('{} 발 남았습니다.'.format(self.bu))
def charge(self,n):
self.bu += n
def shoot(self,a):
for i in range(a):
if self.bu > 0 :
self.bu -= 1
print ('탕 !')
elif self.bu == 0 :
print('총알이 없습니다')
break
print(self)
gun1 = gun()
gun1.charge(10)
gun1.shoot(4)
gun1.print()
gun2 = gun()
gun2.charge(10)
gun2.shoot(4)
gun2.print()
설명: gun1 총과 gun2총은 서로 다른 총입니다.
같은 설계도를 사용했지만 별개의 총이다.
별개의 총이 맞는지 확인해본다.
print(gun1)
print(gun2)
<__main__.gun object at 0x000000000C497828>
<__main__.gun object at 0x000000000C525D30>
print(gun1.__class__)
print(gun2.__class__)
<class '__main__.gun'>
<class '__main__.gun'>
둘은 다른 메모리 주소값을 가지고 있어서
같은 클래스를 쓰는 서로 별개의 오브젝트라는 것을 확인함
문제174. gun class 의 메소드들을 static method들로 변경해서 다시 총을 쏘시오
class gun:
bu = 0
@staticmethod
def charge(n):
gun.bu += n
@staticmethod
def shoot(a):
for i in range(a):
if gun.bu > 0 :
gun.bu -= 1
print ('탕 !')
elif gun.bu == 0 :
print('총알이 없습니다')
break
@staticmethod
def print():
print('{} 발 남았습니다.'.format(gun.bu))
gun1 = gun()
gun1.charge(10)
gun1.shoot(3)
gun1.print()
gun2 = gun()
gun2.shoot(7)
gun2.print()
결과 :
탕 !
탕 !
탕 !
7 발 남았습니다.
탕 !
탕 !
탕 !
탕 !
탕 !
탕 !
탕 !
0 발 남았습니다.
문제175. static method로 선언한 클래스를 이용해서 인스턴스화한 두개의 총의 쏘는 메소드(shoot) 이 서로 같은 메모리를 쓰는지 다른 메모리를 쓰는지 확인하시오
- 9장 목차
- 객체와 클래스
- 클래스의 정의
- __init__() 메소드를 이용한 초기화작ㅇ업
- self에 대한 이해
- 정적 메소드와 클래스 메소드
- 클래스 내부에게만 ㅇ려려있는 프라이빗 멤버
- 상속
- 오버라이딩
- __call()__ 메소드
- for문으로 순회를 할 히 있는 객체 만들기
- 추상기반 클래스
■9.10 마법의 __call__ 메소드
예제:
class sample(object):
def __init__(self):
print("전 생성하면 바로 생성이 돼요")
sample = sample()
설명: __init__ 메소드는 인스턴스를 생성하면 바로 실행이 된ㄷ.
예제2 :
class sampel2(object):
def __call__(self):
print("인스턴스에 괄호를 붙이면 제가 실행돼요")
sample2 = sample2()
sample()
클래스의 인스턴스를 함수처럼 호출하기 위해서
클래스의 __call__ 이란느 매직 메소드를 정의했다
이 원리를 이용해서 클래스를 데코레이터로 구현할 수 있다
어제 우리가 데코레이터로 구현한건 클래스가 아니라 함수였다.
■ 클래스를 데코레이터로 구현하는 예제
from functools import wraps
class onlyadmin(obejct): # 함수에 들어가는 매개변수의 문자열을 받아서
def __init__(self,func): # 대문자로 변환해줌
self.func= func
def __call__(self,*args,**kwargs):
name = kwargs.get('name').upper()
self.func(name)
def greet(name):
print("Hello {}".format(name) )
greet(name = 'Scott')
결과 : Hello Scott
문제176. 위의 onlyadmin 데코레이터를 활용해서 find_job이라는 함수를 강력하게 하시오 !
find_job(name= 'scott')
당신의 직업은 ANALYST 입니다.
from functools import wraps
import pandas as pd
class OnlyAdmin(object):
def __init__(self, func): # 대문자로 변환해주며 함수를 실행해주는 클래스
self.func = func
def __call__(self, *args, **kwargs):
name = kwargs.get('name').upper()
return self.func(name)
@OnlyAdmin
def find_job(name):
emp = pd.DataFrame.from_csv('d:/data/emp.csv')
job = emp[['job']][emp['ename'] == name].values[0][0]
return job
find_job(name='SCOTT')
- 9장 목차
- 객체와 클래스
- 클래스의 정의
- __init__() 메소드를 이용한 초기화작ㅇ업
- self에 대한 이해
- 정적 메소드와 클래스 메소드
- 클래스 내부에게만 ㅇ려려있는 프라이빗 멤버
- 상속
- 오버라이딩
- __call()__ 메소드
- for문으로 순회를 할 히 있는 객체 만들기 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- 추상기반 클래스
■ 9.11 for 문으로 순회를 할 수 잇는 객체 만들기
Iterator 는 next() 메소드로 데이터를 순차적으로 호출하는 object이다.
예제 :
for i in range(5) :
print(i)
우리가 당연하게 사용했던 위와 같은 for 문은 사실 range() 로 생성된 list 가 iterable 하기 때문에 순차적으로
member 들을 불러서 사용이 가능했던 것이다.
x = [1,2,3]
next(x)
■ 9.12 추상 기반 클래스
상속일나 클래스의 재사용을 높임으로써
- 코드의 반복을 줄이고
- 유지보수 비용을 낮추는데 큰 역할을 한다
이러한 상속과 함께 객체지향(object-oriendted) 프로그램의 가장 중요한 특징중 하나가 다형성이다
다형성이란 클래스에 선언된 메서드가 상속 받은 클래스에서 같은 이름으로
오버라이딩 되어 여러 형태로 동작함을 의미한다.
예 : 동물
메소드 : 짓는다 (비어있는 메소드)
↙ ↘
고양이 개
짖는다 메소드 : 야옹 짖는다 메소드 : 멍멍
동물 <--- 아직 덜 구체화된 상태 --> 그래서 객체화 시키기에는
↙ ↘
고양이 개 <---- 구체화 된 상태
동물 넌 너무 추상적이야 그러니 너는 객체를 만들지마
!
그래서 추상 클래는 상속을 위해서 필요하긴 하지만 개체화해서는 안되는 클래스
추상 클래스는 추상 메소드가 있는 클래스를 말한다
추상 메소드는 바디(내용)가 없는 메소드이다.
추상 클래스를 상속 받는 자식 클래스에서 반드시 지켜줘야 할 사항은 ?
추상 클래스내에는 추상 메소드와 일반 메소드들이 있을 텐데
그중에 추상 메소드는 반드시 가져와서 오버라이드 해야한다.
예제:
from abc import ABCMeta, abstractmethod # 파이썬은 추상 클래스를 제공하지 않아서 import받아야한다.
class animal(object):
__metaclss__ = ABCMeta # 추상 클래스로 선언
@abstractmethod # 추상 메소드 선언
def bark(self):
pass # 비어있는 메소드, 상속받는 자식들이 반드시 구현해야 하는 중요한 메서드
class cat(animal):
def __init__(self):
self.sound = '야옹'
def bark(self):
return self.sound
class dog (animal) :
def __init__(self):
self.sound = '멍멍'
def bark(self) :
return self.sound
cat = cat()
dog = dog()
print(cat.bark())
print(dog.bark())
문제177. 음료(beverage) 라는 추상클래스 생성하고
아메리카노(americano)와 카페라떼 (caffelatte) 클래스를
자식 클래스로 생성하시오
추상 클래스를 통해서 반드시 구현해야 하는 데메소드는 음료 가격임
'PYTHON' 카테고리의 다른 글
English stopword , 영어 불용어 (0) | 2018.09.18 |
---|---|
gcp를 이용해서 jupyter notebook / jupyter lab 서버 만들기 (0) | 2018.08.27 |
8장. 모듈 (0) | 2017.09.10 |
7장. 함수 (0) | 2017.09.10 |
6장. if 문과 loop문 (p126) (0) | 2017.09.10 |