class SoccerPlayer(object):
#클래스 예약어 + Class명(상속받는 객체명)
# Class명 : CamelCase로 적기
#CamelCase : 띄어쓰기 부분에 대문자, Class명
#snake_case : 띄어쓰기 부분에 "("추가, 함수명
# 상속받는 객체가 없을 경우 자동 상속되어 생략해도 무방함 => Class명(), Class명
def __init__(self, name : str, position : str, back_number : int): #__ini__ : 객체 초기화 예약 함수로, class를 실행 시 초기화를 하며,
#self은 외부에선 해당 class를 선언한 instance명이고 내부에서는 self로 불림
self.name = name #객체 자신인 self와 객체에 필수로 할당할 name, positon, back_number와 같은 atrribute를 설정
self.position = position #namedtuple과 비슷함
self.back_number = back_number # attribute 지정 시 str, int와 같이 설명을 같이 넣어주면 다른 사용자가 이용하기 용이함
def change_back_number(self, new_number): #특정 atrribute에 행동을 취하는 함수를 생성(method)
# f-string
print(f"선수의 등번호를 변경합니다 : From {self.back_number} to {new_number}")
# % operator string
# print("선수의 등번호를 변경합니다 : From %d to %d" %(self, back_number, new_number))
# format-string
# print("선수의 등번호를 변경합니다 : From {} to {}".format(self.back_number, new_number))
# print("선수의 등번호를 변경합니다 : From {aa} to {bb}".format(aa = self.back_number, bb = new_number))
#가장 나은 건 가시성이 좋으며 속도가 가장 빠른 f-string(가장 최근에 나옴)
self.back_number = new_number
def __str__(self): #print와 동일한 역할
return "Hello, My name is {name}. I Play in {position}".format(name = self.name, position = self.position)
def __add__(self, other): # 더하기 연산 or concat
return self.back_number + other
aa = SoccerPlayer("ko","fw",21)
bb = SoccerPlayer("ko","fw",21)
#여기서 aa,bb는 SoocerPlayer라는 클래스에서 파생된 객체
# aa,bb의 argument는 같으나 다른 인스턴스
Inheritance, Polymorphism, Visibility
상속(Inheritance)
class Person:
def __init__(self,name,age):
self.name = name
slef.age = age
class Korean(Person):
pass
다형성(Polymorphism)
class tmp1:
def __init__(self,string):
self.string = string
def printer(self):
return string
class tmp2(tmp1):
def printer(self):
return f"입력된 문자열은 {self.string} 입니다"
tmp1("나는").printer() # '나는'
tmp2("나는").printer() # '입력된 문자열은 나는 입니다'
Visibility
객체의 정보를 볼 수 있는 레벨을 조절하는 것
누구나 객체 안에 모든 변수를 볼 필요는 없음
1)객체를 사용하는 사용자에게 실수로 정보 수정하는 것을 방지
2) 필요 없는 정보에는 접근을 불가하게 만듬
3) 실제 판매되는 제품의 소스 보호
Encapsulation
class Product:
pass
class Inventory:
def __init__(self):
self.items = []
self.test = "abc"
def add_new_item(self,product):
if type(product) == Product:
self.items.append(product)
print(f"new item added({type(product)})")
else:
raise ValueError("Invalied Item")
def get_number_of_items(self):
return len(self.items)
my_inventory = Inventory()
my_inventory.add_new_item(Product())
# class 내부 변수에 특정한 조건이 없을 경우 외부에서 접근 가능
# 따라서 my_inventory.items에다가 append() 혹은 print() 등을 통해 추가하거나 보는 등의 행동을 제한없이 가능
# 제한하고자 할 경우, attribute 선언 시 변수명에 __ 추가해주면됨(=네임 맹글링 : https://tibetsandfox.tistory.com/21)
# 네임 맹글링을 사용하면 private화 할 수 있지만 완벽한 private은 아님
# 조금 더 찾기 어렵게 만들 뿐
# 단, attribute나 method의 다형성을 억제할 순 있음
class Inventory:
def __init__(self):
self.__items = []
self.test = "abc"
def add_new_item(self,product):
if type(product) == Product:
self.__items.append(product)
print(f"new item added({type(product)})")
else:
raise ValueError("Invalied Item")
def get_number_of_items(self):
return len(self.__items)
my_inventory = Inventory()
my_inventory.items.append("Abc")
# >> AttributeError: 'Inventory' object has no attribute 'items'
my_inventory.items
# >> AttributeError: 'Inventory' object has no attribute 'items'
#단, dir(instance명) 으로 class 내부 변수의 주소를 찾으면 접근 가능
dir(my_inventory) => '_Inventory__items' #items 위치
반대로 정보 은닉을 했지만 items에 접근 허용해줄 수 있음
@property decorator 사용
class Inventory:
def __init__(self):
self.__items = []
self.test = "abc"
@property # property decorator 숨겨진 변수를 반환하게 해줌
# property 데코를 통해 getter의 역할 + 함수를 변수명처럼 사용하게 만들어줌
# https://dojang.io/mod/page/view.php?id=2476
# property 데코는 getter의 역할(반대로 setter는 method명.setter)
def items(self):
return self.__items
def add_new_item(self,product):
if type(product) == Product:
self.__items.append(product)
print(f"new item added({type(product)})")
else:
raise ValueError("Invalied Item")
def get_number_of_items(self):
return len(self.__items)
my_inventory = Inventory()
my_inventory.items # 함수로 만들었지만 변수명처럼 사용 가능
first-class object
def square(n):
return x**2
def cube(n):
return x**3
method = [square, cube]
arg_list = [(0,2),(1,2)]
[method[i](n) for i,n in arg_list] =>[4,8]
inner function
def print_msg(msg):
def printer():
return msg
return printer()
print_msg("hello")
decorator
def star(func):
def inner(*args, **kwargs):
print("*"*5)
func(*args,kwargs)
print("*"*5)
return inner
@star # @star 시 @star 이후의 printer 함수가 star 함수의 agument로 됨
# star(func = printer)
def printer(msg):
print(msg)
printer("hello")