반응형
상속
- 구현된 클래스의 기능(메소드)을 그대로 가져다가 사용하거나 아니면 그기능을 수정하거나 아니면 기능을 추가하거나 할때 사용하는 개념
- 부모클래스의 속성(인스턴스변수와 메소드)들을 자식클래스가 그대로 물려받는 개념
- 확장 개념, 부모클래스와 자식클래스가 합쳐지는 개념
- 부모 클래스 먼저 정의해보자.
class PlayerCharacter:
def __init__(self,hp=100,exp=0):
self.hp = hp
self.exp = exp
def attack(self):
print("공격하기")
self.exp = self.exp + 2
def defend(self):
print("방어하기")
self.exp = self.exp + 1
- 부모클래스를 상속 받는 자식 클래스 정의하자
class Wizard(PlayerCharacter): # 상속 받기
def __init__(self,mp):
self.mp = mp
# super(Wizard,self).__init__() # 2.x 버전대 사용방식
super().__init__() # 부모클래스의 생성자를 실행하겠다.
def magic_skill(self):
print("마법 공격하기")
self.mp = self.mp - 2
player = Wizard(10)
player.attack()
공격하기
player.hp
100
1
player.exp
2
player.attack()
player.exp
공격하기
4
- 상속을 하면 정말 합쳐지는게 맞는지 주소값 확인해봅시다.
class PlayerCharacter:
def __init__(self,hp=100,exp=0):
print(f"부모의 주소값: {id(self)}")
self.hp = hp
self.exp = exp
def attack(self):
print("공격하기")
self.exp = self.exp + 2
def defend(self):
print("방어하기")
self.exp = self.exp + 1
class Wizard(PlayerCharacter): # 상속 받기
def __init__(self,mp):
print(f"자식의 주소값: {id(self)}")
self.mp = mp
# super(Wizard,self).__init__() # 2.x 버전대 사용방식
super().__init__() # 부모클래스의 생성자를 실행하겠다.
def magic_skill(self):
print("마법 공격하기")
self.mp = self.mp - 2
Wizard(30)
자식의 주소값: 140111519357136
부모의 주소값: 140111519357136
<__main__.Wizard at 0x7f6e415718d0>
오버라이딩(Override)
- 부모로부터 받는 메소드를 수정하고 싶을때 자식클래스에서 재정의 한다.
class PlayerCharacter:
def __init__(self,hp=100,exp=0):
self.hp = hp
self.exp = exp
def attack(self):
print("공격하기")
self.exp = self.exp + 2
def defend(self):
print("방어하기")
self.exp = self.exp + 1
class Wizard(PlayerCharacter): # 상속 받기
def __init__(self,mp):
self.mp = mp
# super(Wizard,self).__init__() # 2.x 버전대 사용방식
super().__init__() # 부모클래스의 생성자를 실행하겠다.
def magic_skill(self):
print("마법 공격하기")
self.mp = self.mp - 2
# 메소드 오버라이딩
def defend(self):
print("마법사가 방어하기")
self.exp = self.exp + 3
player = Wizard(20)
print(player.exp)
player.defend()
player.exp
0
마법사가 방어하기
3
- Calculator 클래스를 상속받아 add, sub, mul ,div 메소드를 오버라이딩하여 구현하기
- add, sub, mul ,div 메소드에 num 파라미터의 값이 정수가 아닐 경우
"입력값이 정수가 아닙니다. 입력값을 0으로 변경합니다."
출력과 함께 num 파라미터값을 0 값으로 변경한다.
- mul, div 메소드에 경우 0값이 아규먼트로 들어왔을 경우 연산은 하지 않는다.
class Calculator:
def __init__(self,num=0):
self.num = num
def add(self,num): # 한개의 정수를 입력 받아 self.num 더하기, 반환값 X
pass
def sub(self,num): # 한개의 정수를 입력 받아 self.num 빼기, 반환값 X
pass
def mul(self,num): # 한개의 정수를 입력 받아 self.num 곱하기, 반환값 X
pass
def div(self,num): # 한개의 정수를 입력 받아 self.num 나누기, 반환값 X
pass
def result(self):
return self.num
def reset(self):
self.num = 0
class MyCalculator(Calculator):
def __init__(self,num):
super().__init__(num) # 부모생성자에 아규먼트 넣어주기
def add(self,num):
self.num = self.num + self.check_num(num) # 정수가 아닐경우 0 이 반환됨
def sum(self,num):
self.num = self.num + self.check_num(num) # 정수가 아닐경우 0 이 반환됨
def mul(self,num):
if self.check_num(num): # 0 이 아닐경우는 True!
self.num = self.num * num
def div(self,num):
if self.check_num(num): # 0 이 아닐경우는 True!
self.num = self.num / num
def check_num(self,num):
if type(num) is not int: # num 파라미터가 int가 아닐경우 True!
print("입력값이 정수가 아닙니다. 입력값을 0으로 변경합니다.")
num = 0
return num
mc = MyCalculator(3)
mc.add(3)
mc.result()
mc.reset()
mc.result()
0
- 표준화 스케일링
- 데이터의 평균을 0 분산을 1인 분포로 변환환다.
- 그냥 편차를 표준편차로 나눈거다.
x−μσ
Scaler 클래스를 상속받아 StandardScaler 클래스를 구현하시오
Scaler 클래스 fit_transform 와 transform 를 오버라이딩하시오
fit_transform 에 경우는 인자로 받은 데이터의 평균값과 표준편차를 인스턴스변수에 저장하고
인자로 받은 데이터를 표준화하여 스케일링을 적용하고 반환하시오
transform 에 경우는 저장된 인스턴스변수를 이용하여 입력받은 데이터를 표준화하여 스케일링을 적용하고 반환하시오
class Scaler:
def fit_transform(self,data):
pass
def transform(self,data):
pass
class StrandardScaler(Scaler):
# 메소드 오버라이딩
def fit_transform(self,data):
self.avg_ = self.get_avg(data)
self.std_ = self.get_std(data)
return [ (x - self.avg_) / self.std_ for x in data]
# return self.transform(data)
# 메소드 오버라이딩
def transform(self,data):
return [ (x - self.avg_) / self.std_ for x in data]
def get_avg(self,data):
return sum(data) / len(data)
def get_std(self,data):
avg = self.get_avg(data)
diff_list = [ (avg - x)**2 for x in data]
var = sum(diff_list) / len(data)
return var ** 0.5
data = [3000,3500,4000,9000,8000,12000]
ss = StrandardScaler()
ss.fit_transform(data)
[-1.0787144762791367,
-0.9281961772634433,
-0.7776778782477497,
0.7275051119091854,
0.4264685138777984,
1.6306149060033466]
tmp = ss.transform(data)
tmp
[-1.0787144762791367,
-0.9281961772634433,
-0.7776778782477497,
0.7275051119091854,
0.4264685138777984,
1.6306149060033466]
- 데이터의 평균이 0 인지 확인해보자.
ss.get_avg(tmp)
7.401486830834377e-17
- 분산과 표준편차가 1인지 확인해보자.
ss.get_std(tmp)
1.0
- Scaler 클래스를 상속받아 MinMaxScaler 클래스를 구현하시오
- Scaler 클래스 fit, fit_transform , transform, inverse_transform 를 오버라이딩하시오
- fit 은 데이터의 최소값과 사이즈값(최대값- 최소값)을 인스턴스변수에 저장하는 기능을 구현하시오
- fit_transform 은 데이터의 최소값과 사이즈값(최대값- 최소값)을 인스턴스변수에 저장하는 기능과 함께
입력받은 데이터를 minmax 스케일링을 적용하고 반환하시오
- transform 은 저장된 인스턴스변수를 이용하여 입력받은 데이터를 minmax 스케일링을 적용하고 반환하시오
- inverse_transform 은 minmax 스케일이 적용된 데이터를 입력받아 원래의 수치로 변경하는 기능을 구현하시오.
x−Min(X)Max(X)−Min(X)
- 역변환
x×(Max(X)−Min(X))+Min(X)
class Scaler:
def fit(self,data):
pass
def fit_transform(self,data):
pass
def transform(self,data):
pass
def inverse_transform(self,data):
pass
class MinMaxScaler(Scaler):
def fit(self,data):
self.min_ = min(data)
self.size_ = max(data) - self.min_
def fit_transform(self,data):
self.fit(data)
return [ (x - self.min_) / self.size_ for x in data]
def transform(self,data):
return [ (x - self.min_) / self.size_ for x in data]
def inverse_transform(self,data):
return [ x * self.size_ + self.min_ for x in data ]
data = [3000,3500,4000,9000,8000,12000]
mms = MinMaxScaler()
mms.fit(data)
mms.min_ , mms.size_
(3000, 9000)
tmp = mms.transform(data)
tmp
[0.0,
0.05555555555555555,
0.1111111111111111,
0.6666666666666666,
0.5555555555555556,
1.0]
mms.inverse_transform(tmp)
[3000.0, 3500.0, 4000.0, 9000.0, 8000.0, 12000.0]
non public(private 화)
- private: 인스턴스 변수나 메소드를 클래스 내부에서만 사용하게 하는것
- 바깥에서 사용이 불가능하도록 하는 설정
- 맹글링(mangling) 기법을 이요해서 외부에서 직접적으로 인스턴스변수나 메소드에 접근하는것을 막을수 있다.
class PlayerCharacter:
def __init__(self,hp=100,exp=0):
self.hp = hp
self.exp = exp
def attack(self):
print("공격하기")
self.exp += 2
def defend(self):
print("방어하기")
self.exp += 1
def attacked(self,attack_size):
print("공격받음")
self.hp -= attack_size
class Wizard(PlayerCharacter):
def __init__(self,mp):
super().__init__()
self.__mp = mp # private
def __magic_skill(self): # private
print("마법 공격하기")
self.__mp -= 2
def magic_skill(self):
if self.__mp > 1:
self.__magic_skill()
else:
print("MP가 부족합니다.")
player = Wizard(50)
player.__magic_skill()
player.magic_skill()
마법 공격하기
player = Wizard(1)
player.magic_skill()
MP가 부족합니다.
player.__mp
player.__mp = 100
getter & setter (참고용)
- 인스턴스 변수에 접근할때 특정 로직을 거쳐서 접근시키는 방법
- getter & setter 정의할 인스턴스 변수는 private 화 하자.
class Wizard(PlayerCharacter):
def __init__(self,mp):
super().__init__()
self.mp = mp
self.hp = 0
# getter 세팅할때는 다음의 데코레이터 정의
@property
def mp(self):
print("getter 동작")
return self.__mp
# setter 세팅할때는 getter 의 메소드명.setter
@mp.setter
def mp(self,mp):
print("setter 동작")
if mp < 0:
mp = 0
self.__mp = mp
player = Wizard(5)
player.hp
setter 동작
0
player.mp
getter 동작
5
player.mp = -1
setter 동작
player.mp
getter 동작
0
매직 메소드(이건 중요)
- 메소드 명이 두개의 언더바로 감싸져 있다.
- 파이썬의 다양한 내장함수들이 클래스의 매직 메소드들을 호출하여 결과를 만들어 낸다.
class MyDataset:
def __init__(self,data):
self.data = data
def __call__(self,a):
print(f"{a} 함수 호출 방법처럼 객체를 함수 호출하듯이 만들어주는 메소드")
def __str__(self): # print 함수에 이 클래스의 객체를 넣을경우 이메소드에 리턴값을 출력해준다.
return "My dataset Class"
def __len__(self): # len() 내장함수는 객체의 이 매직메소드를 호출한다고 생각하면 된다.
return len(self.data)
def __getitem__(self,idx): # 인덱싱과 슬라이싱을 가능하게 한다.
return self.data[idx]
data = list(range(50,100))
dt = MyDataset(data)
dt
<__main__.MyDataset at 0x7f2582077b50>
dt(1004)
1004 함수 호출 방법처럼 객체를 함수 호출하듯이 만들어주는 메소드
print(dt)
My dataset Class
len(dt)
50
dt[:5]
[50, 51, 52, 53, 54]
객체 생성시 딕셔너리 데이터를 입력 받아 다음과 같은 예시로 데이터를 반환하는
클래스를 만드시오.
ex)
data = {
"x" : [0.4,0.3,0.8,0.2,0.3,0.9,0.7],
"y" : [0,1,0,0,1,0,0]
}
dt = Dataset(data)
len(dt)
Output:
7
dt[0]
Output:
(0.4, 0)
class Dataset:
def __init__(self,data):
pass
def __len__(self):
pass
def __getitem__(self,idx):
pass
data = {
"x" : [0.4,0.3,0.8,0.2,0.3,0.9,0.7],
"y" : [0,1,0,0,1,0,0]
}
class Dataset:
def __init__(self,data):
self.x = data["x"]
self.y = data["y"]
def __len__(self):
return len(self.y)
def __getitem__(self,idx):
return self.x[idx] , self.y[idx]
dt = Dataset(data)
len(dt)
7
dt[0]
(0.4, 0)
dt[-3:]
([0.3, 0.9, 0.7], [1, 0, 0])
반응형
'python' 카테고리의 다른 글
[python]파이썬 - 모듈(Module), 패키지(Package) (0) | 2023.01.24 |
---|---|
[python]파이썬 - 오류 예외처리 (0) | 2023.01.24 |
[python]파이썬 - 클래스class (0) | 2023.01.24 |
[python]파이썬 - 함수function2 lambda (0) | 2023.01.24 |
[python]파이썬 - 함수function (0) | 2023.01.24 |
댓글