Assignment
Input으로 주어진 list의 각 요소(element)가 해당 list에 몇번 나타나는지 수를 dictionary로 만들어서 리턴해주세요. Dictionary의 key는 list의 요소 값이며 value는 해당 요소의 총 빈도수 입니다.
예를 들어, 다음과 같은 list가 input으로 주어졌다면:
my_list = ["one", 2, 3, 2, "one"]
다음과 같은 dictionary가 리턴되어야 합니다.
{
"one" : 2,
2 : 2,
3: 1
}
* 답
def get_occurrence_count(my_list):
dict={}
for key in my_list:
if key in dict:
dict[key] += 1
else:
dict[key] = 1
# dict[key] = 1 로 새로운 key(key)와 value(1)를 동시에 생성한다
return dict
# 이 함수를 구현 해주세요
list = ["one",2,3,2,"one"]
print(get_occurrence_count(list))
* ex )
# 사전형에 리스트형을 넣을 수 있다
택배 = {'구매':['bcaa','protein'],'반품':['달걀','milk']}
for cnt in 택배:
print(cnt,택배[cnt])
# 리스트형에 사전형을 넣을 수 있다
# 리스트형->사전형을 for문으로 출력시에는 cnt[key값]으로 작성해야한다
computer = [{'cpu':'i5-6500','ram':'18g','graphic':'gtx1060-3g'},
{'cpu':'i7-8700','ram':'24g','graphic':'gtx2080-6g'}]
for cnt in computer:
print(cnt['cpu'],cnt['ram'],cnt['graphic'])
# 사전형에 사전형을 넣을 수 있다
# 사전형->사전형을 for문으로 출력시에는 cnt,사전변수명[cnt][key값]으로 작성한다
student = {'kim':{'age':'26세','address':'안산'},'jung':{'age':'26세','address':'평택'}}
for cnt in student:
print(cnt,student[cnt]['age'],student[cnt]['address'])
자동차를 구입할때 기본 사양의 자동차를 살 수 도 있고, 원하면 여러 옵션을 추가 해서 구입할 수 있습니다. 예를 들어, 가죽 의자 옵션을 추가 한다던가 해서 자동차를 구입할 수 있습니다.
예를 들어, A라는 자동차는 옵션 사항이 40개 정도 된다고 가정해 보겠습니다.
A라는 자동차를 구입하는 함수를 구현한다고 했을때, 모든 옵션 사항을 parameter로 받을려면 parameter수가 40개나 되어야 하므로 함수의 정의 부분이 너무 길어질것입니다.
게다가 대부분의 옵션 사항은 설정이 안될 확률이 높습니다. 그렇다면 40개의 parameter가 사용되지 않는데도 불구하고 정의되어야 하는 상황이 됩니다.
또한, A라는 자동차는 계속해서 업그레이드 되므로 전에는 없던 옵션이 생길 수 있습니다. 혹은 있던 옵션이 사라질 수 도 있습니다. 하지만 이미 정의된 함수를 바꾸려면 코드를 수정하고 다시 재배포 해야 하기 때문에 옵션 사항들을 그때 그때 바꿀수 있는 유동성(flexibility)가 떨어집니다.
그렇다면 이렇게 사전에 정확히 필요한 parameter 수와 구조를 알수 없는 경우는 어떻게 해야할까요?
가장 간단한 방법은 다음처럼 dictionary를 parameter로 받아서 사용하는 것입니다.
def buy_A_car(options):
print(f"다음 사양의 자동차를 구입하십니다:")
for option in options:
print(f"{option} : {options[option]}")
options = {"seat" : "가죽", "blackbox" : "최신"}
buy_A_car(options)
다음 사양의 자동차를 구입하십니다:
seat : 가죽
blackbox : 최신
이렇게 하면 원하는 옵션만 간단하게 설정 할 수 있다는 장점은 있지만 옵션을 dictionary로 받아야만 한다는 제약사항이 있습니다. 만일 옵션을 하나도 추가 안하고 기본사양으로 사는 경우에도 비어있는 dictionary를 넘겨줘야 하는것이죠. 게다가 dictionary가 아닌 다른 타입의 값 (예를 들어 string)을 넘겨주는 오류가 생길 확률도 있습니다.
Keyworded variable length of arguments
그래서 파이썬에서는 keyworded variable length of arguments 라는 기능이 있습니다.
Keyworded variable length of arguments는 이름 그대로 keyword arguments 인데 그 수가 정해지지 않고 유동적으로 변할 수 있는 keyword arguments 입니다.
Keyworded variable length of arguments를 선언 하기 위해서는 parameter 이름앞에 두개의 별표 (**) 로 시작해야 합니다. 예를 들어 다음 처럼 말이죠.
**options
그리고 함수를 호출할때 일반적인 keyword arguments 처럼 사용하면 됩니다. 일반적인 keyword arugments와의 차이점은:
Argument 수를 0부터 N까지 유동적으로 넘겨줄 수 있습니다.
Keyword가 미리 정해져 있지 않기때문에 원하는 keyword를 유동적으로 사용할 수 있습니다.
Keyworded variable length of arguments는 dictionary 형태로 지정됩니다.
Keyworded variable length of arguments를 사용할때 일반적으로 argument 이름을 kwargs 라고 짓습니다. 그래서 대부분 **kwargs 라고 parameter 이름을 정합니다.
앞서 keyworded variable length of arguments는 dictionary 형태로 지정된다고 배웠습니다. 이부분이 약간 혼동될 수 있습니다. 그래서 예를 들어 보겠습니다.
예를 들어, 다음처럼 선언된 함수가 있다면:
def buy_A_car(**kwargs):
print(f"다음 사양의 자동차를 구입하십니다:")
for option in kwargs:
print(f"{option} : {kwargs[option]}")
호출을 할때 다음 처럼 호출 할 수 있습니다
buy_A_car(seat="가죽", blackbox="최신", tint="yes")
그러면 kwargs 파라미터는 다음과 같은 dictionary로 함수에 전해지게 됩니다:
{'seat': '가죽', 'blackbox': '최신', 'tint': 'yes'}
그러므로 함수 body 안에서는 dictionary를 사용하듯이 kwargs를 사용하면 됩니다.
Keyworded variable length of arguments와 동일하지만 keyword 를 사용하지 않고 순서대로 값을 전달하는 방식도 가능합니다. 그건 Non-keyworded variable length of arguments 혹은 그냥 variable length of arguments 라고 합니다. 더 간단하게 variable arguments 라고 하기도 합니다.
Variable arguments를 선언하는 방법은 별표 2개 대신에 1개를 사용해서 선언합니다.
그리고 variable arguments는 tuple로 변환되어 함수에 전달됩니다.
Variable arguments와 keyworded variable arguments 둘다 사용하여 함수를 정의할 수 도 있습니다.
다음 처럼 말이죠:
def do_something(*args, **kwargs):
## some code here...
....
그렇다면 왜 둘다 사용할까요?
둘다 사용하면 어떠한 형태와 수의 argument도 허용 가능한 함수가 됩니다.
즉, parameter에 있어서 굉장히 유동적인 함수가 되는것입니다.
do_something(1, 2, 3, name="정우성", age=45)
do_something(1, 2, 3, 4, 5, "hello", {"주소" : "서울", "국가" : "한국"})
do_something(name="정우성", gender="남", height="187")
do_something(1)
do_something()
Assignment
함수 2개를 구현해주세요. 함수의 이름은 다음과 같아야 합니다.
sum_of_numbers
what_is_my_full_name
함수 sum_of_numbers는 arugment로 주어지는 모든 수를 합한 값을 리턴해야 합니다.
예를 들어, sum_of_numbers(1, 2, 3, 4, 5) 는 15를 리턴해야 하고 sum_of_numbers(1,2)는 3을 리턴해야 합니다.
만일 parameter가 주어지지 않으면 0을 리턴해야 합니다.
what_is_my_full_name 함수는 주어진 parameter중 first_name 과 last_name 이라는 parameter를 조합하여 full name을 리턴해주어야 합니다.
예를 들어, first_name이 "우성" 이고 last_name 이 "정" 이면 "정 우성" 라고 리턴하면 됩니다.
Last name과 first name 사이에 space(빈칸)이 들어가 있어야 합니다.
만일 last_name이 없거나 first_name이 없으면 둘 중하나만 리턴하면 됩니다.
예를 들어, last_name이 없으면 "우성" 이라고 이름만 리턴하면 됩니다,
마지막으로, last_name과 first_name 둘다 없으면 "Nobody" 라고 리턴하면 됩니다.
def sum_of_numbers(*args):
sum = 0
for i in args:
sum += i
return sum
# *은 튜플형이라 for문으로 돌려줘야함
def what_is_my_full_name(**kargs):
fullname =''
if 'first_name' in kargs and 'last_name' in kargs:
fullname = kargs['last_name'] + ' ' + kargs['first_name']
# 아래에서 설명한것과 같이key값은 문자열으로 오므로 '' 따옴표로 감싸줘야함
elif 'first_name' in kargs:
# first_name 이 kargs(사전형)에 key값으로 들어있는지 확인
fullname = kargs['first_name']
elif 'last_name' in kargs:
fullname = kargs['last_name']
else:
return 'Nobody'
return fullname
print(sum_of_numbers(1,2,3,4))
print(what_is_my_full_name())
# first_name , last_name (key값)은 자동으로 문자열로 감 따라서 함수에서 해당 key를 사용할땐 따옴표를 써줘야함
Assignment
함수 2개를 구현해주세요. 함수의 이름은 다음과 같아야 합니다.
sum_of_numbers
what_is_my_full_name
함수 sum_of_numbers는 arugment로 주어지는 모든 수를 합한 값을 리턴해야 합니다.
예를 들어, sum_of_numbers(1, 2, 3, 4, 5) 는 15를 리턴해야 하고 sum_of_numbers(1,2)는 3을 리턴해야 합니다.
만일 parameter가 주어지지 않으면 0을 리턴해야 합니다.
what_is_my_full_name 함수는 주어진 parameter중 first_name 과 last_name 이라는 parameter를 조합하여 full name을 리턴해주어야 합니다.
예를 들어, first_name이 "우성" 이고 last_name 이 "정" 이면 "정 우성" 라고 리턴하면 됩니다.
Last name과 first name 사이에 space(빈칸)이 들어가 있어야 합니다.
만일 last_name이 없거나 first_name이 없으면 둘 중하나만 리턴하면 됩니다.
예를 들어, last_name이 없으면 "우성" 이라고 이름만 리턴하면 됩니다,
마지막으로, last_name과 first_name 둘다 없으면 "Nobody" 라고 리턴하면 됩니다.
https://stackoverflow.com/c/wecode/questions/64
Assignment
Decorator를 구현해보세요.
Decorator는 앞서 배운 closure를 한단계 더 나아가 사용하는 고급 기능입니다.
Decorator는 closure처럼 중첩함수를 리턴하는 함수 이며 다른 함수에 적용해서, 적용된 함수가 실행되기 전에 무조건 실행됩니다. 즉 특정 함수를 실행하기 전에 강제적으로 다른 함수가 먼저 실행된후 실행되도록 하는 강제성을 제공하는 기능입니다.
더 자세한 내용은 아래 링크의 스택오버플로우 질문을 참조하세요:
https://stackoverflow.com/c/wecode/q/64/1
왼쪽 상단의 greeting 함수에 적용될 decorator 함수를 구현하여 greeting 함수에 적용해주세요.
Greeting 함수가 호출 되었을때 decorator 함수에 parametor 값이 greeting 함수 리턴값의 다음에 붙혀져서 리턴되어야 합니다. Decorator 함수의 이름은 name_decorator 여야 합니다.
예를 들어, 다음 처럼 정의 하여 name_decorator decorator에 "정우성"을 parameter로 적용하여 greeting을 호출하면:
@name_decorator("정우성")
def greeting():
return "Hello, "
greeting()
결과값은 다음과 같아야 합니다.
"Hello, 정우성"
* 정답과 해설
def name_decorator(name):
def decorator(func):
def function(*args,**kargs):
return func() + name
return function
return decorator
@name_decorator('정우성')
def greeting():
return "Hello, "
print(greeting())
'''
데코레이터엔 인자값을 쓰지않는다. 하지만 퀴즈에는 데코레이터에 인자값으로 '정우성'을 넘겨주는데,
이것은 중첩함수를 3개를 쓰라는 함정이었다. 먼저 name_decorator 함수로 name을 받아주고, decorator
함수를 반환해주면 decorator함수가 실행되며 인자값으로 func(greeting함수)함수를 받아온다.
greeting 다시 decorator함수가 function함수를 반환해주면 function함수는 func()를 호출하며 + name
으로 뒤에 정우성을 붙힐 수 있다.
참고로 function함수의 인자값으로 *args 와 **kargs를 안받아도 실행이된다
자세한건 오늘 집가서 데코레이터에 대해 더 알아볼 예정이다
'''
Scope은 범위라는 뜻입니다.
프로그래밍 언어에서 scope은 어떠한 객체 (변수, 함수 등)가 유효한 범위를 이야기 합니다.
범위를 벗어나면 해당 객체는 사용될 수 없습니다.
Python에서 scope은 항상 객체가 선언된 지점에서 위로는 상위 객체 까지, 아래로는 모든 하위 객체들과 그 안에까지가 범위 입니다. 어떤 뜻인지 차근 차근 보겠습니다.
범위에는 크게 다음 4가지가 있습니다.
Local Scope
Enclosed Scope
Global Scope
Built-in Scope
Local Scope이 가장 범위가 제한적이고 built-in scope이 가장 범위가 광범위합니다.
Local Scope
Local scope을 가지고 있는 변수나 함수 혹은 객체는 이름 그대로 특정 범위에서만 유효합니다.
주로 함수 안에서 선언된 변수나 함수가 local scope을 가지고 있습니다. 그리고 이러한 변수들은 해당 함수 안에서만 유효합니다.
Enclosing Scope
Enclosing Scope는 중첩함수가 있을때 적용되는 scope입니다.
부모 함수에서 선언된 변수는 중첩함수 안에서도 유효한 범위를 가지고 있습니다.
Global Scope
Global scope은 함수 안에서 선언된것이 아닌 함수 밖에서 선언된 변수나 함수를 이야기 합니다.
본 강의에 앞부분에서 설명했듯이, 변수나 함수는 선언된 지점과 동일한 level의 지역, 그리고 더 안쪽의 지역들까지 범위가 유효합니다.
그리고 global scope을 가지고 있는 변수와 함수들은 선언된 지점이 해당 파일에서 가장 바깥쪽에서 선언되므로 해당 파일에서 선언된 지점 아래로는 다 유효한 범위를 가지고 있습니다. 그래서 "Global" scope 이라고 하는 것입니다.
Built-in Scope
Built-in scope은 scope중 가장 광범위한 scope입니다.
파이썬안에 내장되어 있는, 파이썬이 제공하는 함수 또는 속성들이 built-in scope를 가지고 있습니다.
그리고 built-in scope는 따로 선언이 없이도 모든 파이썬 파일에서 유효한 범위를 가지고 있습니다.
예를 들어, list등과 같은 자료구조의 element 총 개수를 리턴하는 len 함수가 바로 built-in scope를 가지고 있습니다.
Shadowing
파이썬은 변수나 함수의 정의를 찾을때 다음 순서의 scope들 안에서 찾습니다.
Local => Enclosing => Global => Built-in
즉 가장 좁은 유효범위 부터 시작 해서 넓은 범위로 나아가며 사용되는 변수나 함수의 정의를 찾습니다.
그러므로 만일 동일한 이름의 변수들이 서로 다른 scope에서 선언이 되면 더 좁은 범위에 있는 변수(혹은 함수)가 더 넓은 범위에 있는 변수를 가리는 (shadowing)효과가 나타납니다.
Class를 영어사전에서 찾아보면 다음과 같은 뜻을 가지고 있습니다.
보시다시피 굉장히 많은 뜻을 가지고 있습니다.
그 중 코딩에서 사용되는 class 라는 단어가 가지는 의미는 "부류" (위 이미지 가장 하단에 나와있는) 에 가장 가깝습니다.
그럼 "부류" 라는건 무엇일까요? 영어로는 kind, category의 의미를 가지고 있습니다.
부류를 국어사전에서 찾아보면 다음과 같은 의미들이 나옵니다.
부류의 뜻은 "동일한 범주에 속하는 대상들을 일정한 기준에 따라 나누어 놓은 갈래" 라고 국어사전에 나옵니다.
비슷한 사람들을 가리켜 "저들은 같은 부류의 사람들이다" 라고 합니다. 즉 공통점이 많은 사람들을 가리켜 "같은 부류" 라고 하는 것입니다.
예를 들어, 요즘 인기가 많은 TV 프로그램인 "전지적 참견 시점"의 출연자인 이영자, 송은이, 양세형, 유병재는 공통점이 있습니다. 바로 4명 다 코미디언 이라는 점입니다 (네, 전현무는 코미디언 이라고 하기엔 애매모호 해서 뺐습니다. 전현무, 코미디언 인가요?).
그러므로 이 4명은 같은 부류라고 할 수 있겠죠. 하지만 그렇다고 이영자, 송은이, 양세형, 유병재가 동일 인물은 절대 아닙니다. 이 4명은 개개인이 틀린 사람이지만 공통점을 가지고 있는 부류 인거죠.
즉 Comedian 이 class 가 됩니다.
그러나 comedian이라는 것은 개념일 뿐입니다.
Comedian의 실체 (instanace) 는 이영자, 송영이, 양세형, 유병재입니다.
이 실체(instance)들을 object(객체) 라고 합니다.
사람이 아닌 사물로 예를 하나 더 들어보겠습니다.
여러분이 제일 좋아하는 차는 무엇인가요?
저는 개인적으로 Lexus를 좋아합니다. (아직 가지고 있진 않습니다 😅)
Lexus, BMW, Benz, Hyundai 등 모두 자동차 입니다.
그럼 여기서 class 는 무엇일까요?
네, 자동차가 class 입니다.
그럼 자동차라는 개념의 실체(instance)는 무엇일까요?
네, Lexus, BMW, Benz, Hyundai 입니다.
Class 정의 하기
자 이제 그럼 앞서 본 Car class 와 obejct 들을 파이썬 코드로 구현해 보겠습니다.
먼저 class가 정의되어야 합니다.
파이썬에서 class를 선언하기 위해서는 다음과 같이 class 키워드를 사용하면 됩니다:
class ClassName:
...class 내용 코드들
참고로 class 이름은 각 단어의 앞글자를 대문자로 사용합니다.
예를들어, Car, Comedian 처럼 말이죠. 만일 한단어 이상으로 이루어져 있다면 밑줄(underscore) 없이 모든 단어를 다 붙이되 각 단어의 앞글자는 대문자로 해서 단어를 구분하게 됩니다. 다음 처럼 말이죠:
ScotchWishkey
SomeReallyLongClassName
Car class는 다음처럼 정의 할 수 있습니다.
class Car:
pass
class가 정의되면, class로 부터 실체화(instantiate) 할 수 있습니다. 클래스를 실체화 하는 방법은 간단합니다. 다음과 같이 함수를 호출 하듯이 클래스도 호출 하면 됩니다.
hyundai = Car()
bmw = Car()
Car class를 실체(instance)화 한것이 hyundai와 bmw라는 객체(object) 인것입니다.
하지만 Car class는 아직 아무것도 안하는 비어있는 class 입니다.
앞서 class는 부류 라고 배웠습니다. 그리고 부류란 어떠한 공통점들을 가지고 있는 것/사람 들을 이야기 한다고 배웠습니다.
즉 공통점이 중요한데요, 자동차라면 브랜드, 엔진의 마력, 연비 등등이 공통 요소가 될것 입니다.
이러한 공통 요소들을 class 에서 정의를 해주어야 합니다.
그럼 하나 하나씩 공통 요소들을 정의해 보겠습니다.
Class의 attribute(속성)
class에 정의되는 공통 요소들을 전문어로 class의 attribute(성질 혹은 속성) 이라고 합니다.
모든 자동차는 다음과 같은 공통 요소를 가지고 있습니다.
Maker (현대, BMW 등)
모델명 (BMW305, 제네시스 등)
마력 (horse power)
이 외에도 많겠지만 예제의 간단함을 위해서 위 3개만 고려하겠습니다.
위 3개의 속성들을 class에서 정의하기 위해서는 다음과 같이 init 함수를 통해서 정의 해주면 됩니다.
(참고로 class 안에서 정의해주는 함수(function)는 function이라고 하지 않고 method 라고 합니다)
class Car:
def init(self, maker, model, horse_power):
self.maker = maker
self.model = model
self.horse_power = horse_power
init 함수의 작동 원리를 이해하는것이 복잡할 수 있습니다.
그러나 차근 차근 풀어나가면 쉽습니다. 그러니 차근 차근 풀어나가 보겠습니다.
먼저 init 메소드의 이름을 자세히 보겠습니다. init 이라는 단어의 앞 뒤에 밑줄 2개가 있습니다.
이렇게 앞뒤로 밑줄 2개가 있는 메소드들을 special methods라고 합니다. 이들은 특별 취급을 받습니다.
그 중 init 메소드는 class가 실체화 될때 사용되는 함수 입니다.
예를 들어:
hyundai = Car("현대", "제네시스", 500)
여기서 이미 init 메소드가 호출이 됐습니다. init 이라고 메소드 이름을 명확하게 명시하지는 않았지만 클래스가 실체화 될때 자동으로 init 메소드가 호출이 됩니다.
자 근데 여기서 이상한점이 있습니다. 눈치 채셨나요?
네, init 메소드의 parameter는 총 4개인데, 앞서 클래스를 실체화 할때는 3개만 넘겨주었습니다.
self 파라미터를 빼먹었는데요, 이 self 파라미터는 도대체 무엇이길래 빼먹는걸까요?
self를 이해하기가 조금 헷갈릴 수 있으니 잘 따라오세요!
코딩을 배울때 새로운 개념을 만나면 우리는 항상 해당 개념의 이름을 잘 이해해야 합니다.
그래야 개념 잡기가 쉽습니다.
그래서... self의 뜻은 바로 "자신" 이죠. 그래서 Myself 하면 "나 자신" 이고 yourself 하면 "너 자신"을 이야기 합니다.
그렇다면 class에서 "self" 는 누구를 말하는 걸까요? Class 자체를 말하는것은 아닐겁니다.
왜냐하면 앞서 보았듯이 class 자체는 공통점이 있는 부류를 가리키는 개념 이기 때문입니다.
반면에 self는 어떠한 실체를 가르키는 단어입니다.
그렇다면... 당연히 class에서 self는 class의 실체(instance)를 가르키겠죠!!! 🤔🤨🤩
네, self는 class의 실체(instance)인 객체(object)를 가르킵니다!
그러므로 Car class에서 "self" 는 Car class의 객체인 hyundai나 bmw를 가르키는 거죠.
그리고 클래스를 실체화 할때 파이썬이 해당 객체(self)를 자동으로 init 함수에 넘겨줍니다.
자, 내용이 많은데 정리하자면:
init 메소드는 클래스가 실체화 될때 자동으로 호출이 된다.
init 메소드의 self 파라미터는 클래스가 실체화된 객체를 넘겨주어야 하며, 파이썬이 자동으로 넘겨준다.
init 메소드의 self 파라미터는 항상 정의되어야 있어야 하며 맨 처음 파라미터로 정의 되어야 한다 (그래야 파이썬이 알아서 넘겨줄 수 있으므로)
이제 init 메소드의 호출 작동 원리에 대해서는 다 이해가 되셨죠??
그럼 이제 init 메소드 안에 코드를 보겠습니다.
class Car:
def init(self, maker, model, horse_power):
self.maker = maker
self.model = model
self.horse_power = horse_power
Parameter로 넘겨진 maker, model, 그리고 horse_power 값을 동일한 이름으로 self 에 저장 하는 것을 볼 수 있습니다. 왜 저러는 거죠??
self 는 객체라고 방금 배웠습니다. 그러므로 객체에 maker, model, 그리고 horse_power를 저장하는걸 알 수 있습니다. 근데 왜 저장하는 걸까요?
저장하는 이유는 나중에 다시 사용하기 위해서 입니다.
더 자세히 이야기하면 다른 메소드에서 사용하기 위함입니다!
Class Method
클래스에서 init 말고도 다른 메소드를 원하는 대로 추가할 수 있습니다.
Method와 attribute(속성)의 차이는 명사와 동사의 차이라고 생각하시면 됩니다.
속성은 해당 객체의 이름 등의 정해진 성질인 반면에 메소드는 move, eat 등 객체가 행할 수 있는 어떠한 action같은 느낌이라고 생각할 수 있습니다.
그럼 자동차가 할 수 있는 action은 무엇이 있을까요?
움직이기, 멈추기, 경적 울리기 등이 있을 수 있습니다.
그럼 "경적 울리기"를 메소드로 추가해 보겠습니다.
class Car:
def init(self, maker, model, horse_power):
self.maker = maker
self.model = model
self.horse_power = horse_power
def honk(self):
return "빠라바라빠라밤"
honk 메소드에도 self 가 들어가 있는걸 볼 수 있습니다.
모든 메소드에는 self 파라미터가 첫번째 파라미터로 들어가야 합니다.
honk 함수는 다음 처럼 사용할 수 있습니다.
hyundai = Car("현대", "제네시스", 500)
hyundai.honk()
"빠라바라빠라밤"
네 이렇게 객체에서 메소드를 사용할때는 dot(.) 을 사용하여 객체를 호출 합니다. 즉
<객체>.<메소드>
이를 dot notation 이라고 합니다. 이미 많이 보셨을 겁니다.
자, 근데 이제 우리나라 법이 바뀌어서 모든 차는 경적소리에 해당 차의 회사명이 들어가야 한다고 합시다.
예를 들어, 현대차이 경적소리에는 "현대 빠라바라빠라밤" 이라고 나야 합니다.
근데 honk 메소드에서 해당 객체의 회사 정보를 어떻게 알 수 있을까요?
다행히도 init 메소드에서 self 객체에 해당 정보들을 저장해 놓았기 때문에 다음처럼 사용하면 됩니다.
class Car:
def init(self, maker, model, horse_power):
self.maker = maker
self.model = model
self.horse_power = horse_power
def honk(self):
return f"{self.maker} 빠라바라빠라밤"
hyundai = Car("현대", "제네시스", 500)
hyundai.honk()
"현대 빠라바라빠라밤"
(참고로 빠라바라바라밤 은 90년도때 오토바이 소리로 유명했습니다)
Class는 어디다 쓰나요?
지금까지 클래스에 대해서 배워봤습니다.
근데 클래스는 언제, 어떻게 쓰는걸까요?
사실 클래스 없이도 코드를 구현할 수 있습니다.
하지만 클래스를 쓰는 이유는, 클래스를 사용하면 코드의 구조를 더 효과적으로 구현할 수 있기 때문입니다.
앞서 본 Car 의 예제 코드를 class를 사용하지 않고 구현한다고 생각해보세요. 어떻게 구현할 수 있을까요?
네, 벌써 머리가 아프죠?
이렇게 코드를 클래스 위주로 작성하는 것을 object oriented programming(객체 지향 프로그래밍) 이라고 합니다. 개발자들이 많이 사용하는 단어 이니 기억해두시길 바랍니다.