Unit 32. 람다 표현식 사용하기
람다 표현식은 식 형태로 되어 있다고 해서 람다 표현식 이라고 부른다. 함수를 간편하게 작성할 수 있어서 다른 함수의 인수로 넣을 때 주로 사용한다.
32.1 람다 표현식으로 함수 만들기
다음은 숫자를 받은 뒤 10을 더해서 반환하는 함수 이다.
람다 표현식은 lambda에 매개변수를 저장하고 :(클론) 뒤에 반환 값으로 사용할 식을 지정한다. 이 함수를 람다 표현식으로 작성하면 다음과 같다.
실행을 해보면 함수 객체가 나오고, 이 상태로는 함수를 호출할 수 없다. 람다 표현식은 이름이 없는 익명 함수이기 때문이다. lamda로 만든 익명 함수를 호출하려면 다음과 같이 람다 표현식을 변수에 할당해야 한다.
위 람다 표현식은 매개변수로 x를 받고, x에 10을 더해 반환한다는 뜻이다.
32.1.1 람다 표현식 자체를 호출하기
람다표현식은 변수에 할당하지 않고, 람다표현식 자체를 괄호로 묶고, 다시 괄호를 붙여 괄호 안에 인수를 넣어 호출할 수 있다.
32.1.2 람다 표현식 안에서는 변수를 만들 수 없다
람다 표현식은 변수 표현식 안에서 새 변수를 만들 수 없다. 반환값 부분은 변수의 생성 없이 한 줄로 표현할 수 있어야 한다. 새 변수를 만드는 코드를 넣으면 에러를 발생한다.
표현식 밖에서 선언된 변수는 사용할 수 있다.
31.1.3 람다 표현식을 인수로 사용하기
def로 만든 함수에서 map을 사용하여 리스트를 plus_ten() 함수에 넣으면 매개변수에 10을 더해서 반환하므로 리스트의 각 요소들은 10씩 더해진다.
map의 함수 자리에 람다 표현식을 넣어도 된다.
람다 표현식을 사용하면 세줄이였던 위의 코드를 1줄로 줄일 수 있다.
람다 표현식으로 매개변수가 없는 함수를 만들때는 lamba뒤에 아무것도 지정하지 않고 클론을 붙인 후 반환값을 지정한다.
32.2 람다 표현식과 map, filter, reduce 함수 사용하기
32.2.1 람다 표현식에 조건부 표현식 사용하기
람다 표현식에 조건부 표현식을 사용하는 방법은 다음과 같다.
lambda 매개변수들: 식1 if 조건식 else 식2
다음은 map을 사용하영 3의 배수를 문자열로 변환하는 것이다.
리스트의 요소를 각각 처리했기 때문에 반환값도 요소로 나온다. 요소가 3의 배수일 때는 문자열로 변환하였다.
람다 표현식 안에서 조건부 표현식(if, else)을 사용할 때는 클론을 붙이지 않는다. 조건부 표현식은 '식1 if 조건식 else 식2' 형식으로 사용하며 조건식이 참이면 식1을, 거짓이면 식2 를 사용한다. 람다 표현식에서 if를 사용하면 반드시 else를 사용해야 한다. else를 사용하지 않으면 에러가 발생한다.
람다 표현식에서는 elif를 사용할 수 없다. 따라서 람다 표현식에서는 다음과 같이 if를 연달아서 사용해야 한다.
lambda 매개변수들: 식1 if 조건식1 else 식2 if 조건식2 else 식3
다음은 리스트에서 1은 문자열로 변환하고, 2는 실수로 변환하고, 3이상의 수는 10을 더하는 코드이다.
식이 알아보기 복잡하기 때문에 이와 같은 경우에는 코드의 길이가 길어지더라도 알아보기 쉽게 작성하는것이 좋다.
32.2.2 map에 객체를 여러 개 넣기
map은 리스트 등 반복 가능한 객체를 여러개 넣을 수 있다. 다음은 두 리스트의 요소들을 곱해서 새로운 리스트를 만든다.
리스트 두개를 처리할 때는 람다 표현식에서 매개변수를 두 개 지정하고, 리스트 두 개를 콤마로 구분해서 넣어준다. 람다 표현식의 매개변수의 개수에 맞게 반복 가능한 객체도 콤마로 구분하여 넣어주면 된다.
32.2.3 filter 사용하기
filter는 반복 가능한 객체에서 특정 조건에 맞는 요소만 가져온다. filter에 지정한 함수가 True를 반환할 때만 해당 요소를 가져온다.
다음은 def로 함수를 만들어 리스트에서 5보다 크고 10보다 작은 숫자만 가져오는 함수이다.
함수 f를 람다표현식으로 만들면 다음과 같다.
람다 표현식에 조건식을 넣어 True인 요소만 가져오도록 하였다.
32.2.4 reduce 사용하기
reduce는 반복 가능한 객체의 각 요소를 지정된 함수로 처리한 뒤 이전 결과와 누적하여 반환하는 함수이다.
reduce는 내장함수가 아니라 functools모듈에 있다.
다음은 리스트에 저장된 요소를 순서대로 더한 뒤 누적한 결과를 반환하는 코드이다.
함수 f를 람다 표현식으로 만들어 reduce에 넣으면 다음과 같다.
매개변수 x,y를 지정하고 x와 y를 더한 값을 반환하도록 하였다.
32.3 퀴즈
정답은 d 이다.
정답은 b이다.
정답은 c이다.
32.4 연습문제: 이미지 파일만 가져오기
정답은 다음 코드와 같다.
list(filter(lambda x: x.find('jpg') != -1 or x.find('png') != -1, files))
find()메서드는 찾는 문자열이 있으면 그 문자열의 인덱스를 반환하고, 없으면 -1을 반환한다. 둘중 하나만 참이 되면 되므로 or연산자를 사용하여 람다 표현식으로 조건식이 True 가 나오는 요소들을 가져왔다.
32.5 심사문제: 파일 이름을 한꺼번에 바꾸기
정답은 다음 코드와 같다.
list(map(lambda x : '{0:03d}.{1}'.format(int(x.split('.')[0]), x.split('.')[1]), files))
files의 각 요소들을 .을 기준으로 나누어 숫자는 0을 채운 3자리로 만들어 다시 확장자를 더해서 리스트에 담았다.
Unit 33. 클로저 사용하기
33.1 변수의 사용 범위 알아보기
파이썬 스크립트에서 변수를 만들면 다음과 같이 함수 안에서도 사용할 수 있다.
x = 10
def foo():
print(x)
foo()
print(x)
위 변수 x처럼 함수를 포함하여 스크립트 전체에서 접근할 수 있는 변수를 전역변수 라고 하며, 전역 변수에 접근할 수 있는 범위를 전역 범위라 한다.
x를 함수 안에 지정하면 함수 밖에서는 x를 출력할 수 없다.
def foo():
x = 10
print(x)
foo()
print(x)
x가 정의되지 않았다는 에러가 발생한다. 변수 x는 함수 안에서 만들어 졌기 때문에 함수 안에서만 접근할 수 있는 지역변수이다. 지역변수를 접근할 수 있는 범위를 지역 범위라고 한다.
33.1.1 함수 안에서 전역 변수 변경하기
x = 10
def foo():
x = 20
print(x)
foo()
print(x)
위 코드는 함수 안에서 x의 값을 20으로 변경했지만, 함수 밖에서 출력하면 10이 나왔다. 함수 안의 x는 그 함수의 지역 변수이다. 함수 밖의 x와 함수 안의 x는 이름만 같을 뿐 서로 다른 변수이다.
함수 안에서 전역변수의 값을 변경하려면 global이라는 키워드를 사용해야 한다.
x = 10
def foo():
global x
x = 20
print(x)
foo()
print(x)
함수 안에서 변수를 global로 지정하면 전역 변수로 사용할 수 있고, 해당 전역 변수가 없으면 해당 변수는 전역변수가 된다.
def foo():
global x
x = 20
print(x)
foo()
print(x)
네임 스페이스
파이썬에서 변수는 네임 스페이스에 저장된다. locals함수를 사용하면 현제 네임스페이스를 딕셔너리 형태로 출력할 수 있다.
다음과 같이 함수 내에서 locals함수를 사용하면 함수의 지역 범위 내의 네임스페이스를 출력할 수 있다.
33.2 함수 안에서 함수 만들기
다음과 같이 def로 함수를 만들고, 그 안에서 다시 def로 함수를 만들면 된다.
def 함수이름1():
코드
def 함수이름2():
코드
다음은 함수 안의 함수로 문자열을 출력하는 함수이다.
def print_hello():
hello = 'hello world'
def print_message():
print(hello)
print_message()
print_hello()
print_hello 함수 안에 print_message 함수를 만들었다. hello변수는 print_hello 안에 있으며, print_message함수에서 hello변수를 출력한다. print_hello 함수 안에서는 print_message 함수를 실행한다. 두 함수가 실제로 동작하려면 print_hello를 호출하면 print_hello > print_message 순서로 실행된다.
33.2.1 지역변수의 범위
위의 코드에서 안쪽 함수 print_message에서는 바깥쪽 함수 print_hello의 지역변수 hello를 사용할 수 있다. 바깥쪽 함수의 지역 변수는 그 안에 속한 모든 함수에서 접근할 수 있다.
33.2.2 지역변수 변경하기
def A():
x = 10
def B():
x = 20
B()
print(x)
A()
A함수에서 변수 x에 10을 할당하고, A안의 B함수에서 변수 x에 20을 할당하고 B를 호출하고 x를 출력하는 A함수를 실행했다. 결과값은 10이 나왔다. B함수에서 바깥쪽 함수의 지역변수 x를 변경하는 것이 아니라 안쪽 함수 B에서 이름이 같은 지역변수 x를 새로 만드는 것이다. 파이썬에서는 함수에서 변수를 만들면 항상 현재 함수의 지역변수가 된다.
현재 함수 바깥쪽에 있는 지역변수의 값을 변경하려면 nonlocal 키워드를 사용해야 한다.
def A():
x = 10
def B():
nonlocal x
x = 20
B()
print(x)
A()
nonlocal키워드로 바깥쪽 함수의 지역변수의 값을 변경한 것을 확인할 수 있다.
nonlocal은 현재 함수의 지역변수가 아니라는 뜻이기 때문에 바깥쪽 함수의 지역변수를 사용한다.
33.2.3 nonlocal이 변수를 찾는 순서
def A():
x = 10
y = 100
def B():
x = 20
def C():
nonlocal x
nonlocal y
x += 30
y += 300
print(x)
print(y)
C()
B()
A()
함수 C에서 nonlocal 키워드를 사용하게 되면 변수 x는 바깥쪽의 b 함수의 지역변수 x = 20을 사용하게 된다. 변수 y는 B 함수에는 없기 때문에 한단계 더 바깥으로 나가서 A 함수의 y 변수를 사용하게 된다. nonlocal은 가까운 함수부터 지역변수를 찾고, 지역변수가 없으면 계속 밖으로 나가서 찾는다.
nonlocal 키워드를 사용했는데, 바깥쪽 함수에 nonlocal로 지정한 변수가 없다면 위와 같은 에러를 발생시킨다.
33.2.4 global로 전역변수 사용하기
x = 1
def A():
x = 10
def B():
x = 20
def C():
global x
x += 30
print(x)
C()
B()
A()
함수가 몇단계든 상관없이 global키워드를 사용하면 무조건 전역변수를 사용하게 된다. 함수 C에서만 전역변수를 사용했기 때문에 x+=30 은 31이된다.
33.3 클로저 사용하기
다음은 함수 바깥 쪽에 있는 지역변수 a,b를 사용하여 a * x + b를 계산한 뒤 반환한다.
def calc():
a = 3
b = 5
def mul_add(x):
return a * x + b
return mul_add
c = calc()
print(c(1), c(2), c(3), c(4), c(5))
calc함수에 변수 a,b를 만들고 3과 5를 저장하였다. mul_add 함수에서는 a 와 b를 사용하여 a * x + b를 반환한다. 이후 calc 함수에서 mul_add 함수 자체를 반환한다. 함수를 반환할 때는 함수 이름만 반환하며 괄호를 붙이지 않는다.
함수 calc를 호출하고 반환값을 c에 저장하면 calc에서 mul_add를 반환했으므로 c에는 함수 mul_add가 들어간다.
print(c)를 통해 c를 출력해보면 mul_add함수 자체만 들어간 것을 알 수 있다.
그리고 c에 숫자를 넣어 호출하면 계산식에 따라 연산한 값이 출력된다.
함수 calc가 끝났는데도, calc의 지역변수 a,b를 사용하여 계산을 하고 있다. 이렇게 함수를 둘러싼 환경을 유지하다가 함수를 호출할 때 다시 꺼내서 사용하는것을 클로저 라고 한다.
c에 저장된 함수가 클로저 이기 때문에 위 그림처럼 calc함수 내의 지역변수를 가져와서 사용할 수 있다.
클로저를 사용하면 프로그램의 흐름을 변수에 저장할 수 있고, 지역변수와 코드를 묶어서 사용하고 싶을 때 활용한다.
또한 클로저에 속한 지역변수는 밖에서 직접 접근할 수 없기 때문에 데이터를 숨기고 싶을때 사용한다. 함수 외부에서 데이터의 변경이 일어나면 안될 때 사용해도 좋을것 같다.
33.3.1 lambda로 클로저 만들기
클로저는 다음과 같이 람다로도 만들 수 있다.
def calc():
a = 3
b = 5
return lambda x: a * x + b
c = calc()
print(c(1),c(2),c(3))
람다는 이름이 없는 익명함수 이고, 클로저는 함수를 둘러싼 환경을 유지했다가 나중에 다시 사용하는 함수를 뜻한다.
33.3.2 클로저의 지역변수 변경하기
클로저의 지역변수를 변경하고 싶으면 다음과 같이 nonlocal을 사용한다.
def calc():
a = 3
b = 5
total = 0
def mul_add(x):
nonlocal total
total = total + a * x + b
print(total)
return mul_add
c = calc()
c(1)
c(2)
c(3)
a * x + b의 결과를 calc함수의 지역변수 total에 누적한다.
33.4 퀴즈
정답은 b,d이다. 함수 안에서 전역변수의 값을 바꿀 때는 global을 사용하고, 함수 안에 함수가 여러 단계 있어도 전역변수를 사용할 수 있다.
정답은 c,d이다. 지역변수는 함수 바깥쪽에서 사용할 수 없고, nonlocal을 이용하면 두단계 이상 바깥쪽에 있는 지역변수도 사용할 수 있다.
정답은 c,d이다. 람다는 익명함수를 의미하므로 다른 의미이다. 클로저는 람다 표현식으로 만들 수 있다.
33.5 연습문제 : 호출 횟수를 세는 함수 만들기
정답은 다음코드와 같다.
nonlocal i
i += 1
return i
return count
conunt 함수에서 counter 함수의 지역변수 i를 사용하여 counte 함수가 실행될 때마다 1씩 누적하고 누적한 값을 반환하며 counter 함수에서 count함수를 반환하게 하였다.
33.6 심사문제: 카운트 다운 함수 만들기
정답은 다음 코드와 같다.
i = n+1
def down():
nonlocal i
i -= 1
return i
return down
입력한 값을 포함하여 숫자를 세야 하므로 countdown 함수의 지역변수 i를 입력값보다 1 크게 하고, down함수를 만들어 i를 1씩 감소시킨 후 반환하였다. countdown 함수는 down 함수를 반환하였다.
Unit 34. 클래스 사용하기
클래스는 객체를 표현하기 위한 문법이다. 클래스는 게임속의 다양한 직업들, 웹 브라우저 에서 사용하는 스크롤바, 버튼, 체크박스 등 같은 개념을 사용하는 객체를 묶은 것이다. 객체는 스크롤바, 버튼, 체크박스처럼 특정한 개념이나 모양으로 존재하는 것이다. 프로그래밍에서 객체를 만들 때 클래스를 사용한다.
게임의 캐릭터를 클래스로 표현하면 캐릭터는 체력, 마나, 공격력 등이 필요하며 칼로 찌르기, 베기 등의 스킬이 있어야한다.
체력, 마나, 공격력 등을 속성(attribute)라 하고, 찌르기, 베기 등의 스킬을 메서드(method)라 한다.
이런 프로그래밍 방법을 객체 지향 프로그래밍이라고 한다. 객체 지향 프로그래밍은 복잡한 문제를 잘게 나누어 객체로 만들고, 객체를 조합하여 문제를 해결한다. 기능을 개선하고 발전시킬때도 해당 기능을하는 클래스만 수정하면 되서 유지보수도 효율적이다.
지금까지 사용했던 숫자, 문자, 리스트, 딕셔너리 등도 다 각각의 객체이다.
34.1 클래스와 메서드 만들기
클래스는 class에 이름을 지정하고 클론을 붙인 뒤 다음줄 부터 def로 메서드를 작성하면 된다. 메서드는 클래스 안에 들어있는 함수들이다.
파이썬에서는 보통 클래스 이름은 대문자로 시작한다. 메서드 작성 방법은 함수와 같고, 코드는 반드시 들여쓰기를 해야 한다. 메서드의 첫번째 매개변수는 반드시 self를 지정해야 한다.
class 클래스이름:
def 메서드(self):
코드
다음은 간단한 사람 클래스 이다.
다음과 같이 클래스에 괄호를 붙인뒤 변수에 할당하면 사용할 수 있다.
변수 james를 클래스의 인스턴스라고 한다. 클래스는 특정 개념만 표현할 뿐 사용하려면 인스턴스를 생성해야 한다.
34.1.1 메서드 호출하기
메서드는 인스턴스를 통해 호출된다. 다음과 같이 인스턴스 뒤에 .(점)을 붙이고 메서드를 호출하면 된다.
위와 같이 인스턴스를 통해 호출하는 메서드를 인스턴스 메서드라고 인스턴스 메서드 라고 부른다.
34.1.2 파이썬에서 흔히 볼 수 있는 클래스
지금까지 사용한 int, list, dict등도 클래스 이다. 이 클래스로 인스턴스를 만들고, 메서드를 사용한 것이다.
위와 같은 코드들은 int 클래스로 인스턴스 a를 만들고, list클래스로 인스턴스 b를 만들고, dict클래스로 인스턴스 c를 만든 것이다. 정수를 만들 땐 int를 생략하고, 리스트, 딕셔너리는 [ ], { }을 이용하여 만들지만 이것들도 다 클래스 이다.
위 코드는 인스턴스 b에서 append라는 메서드를 호출하여 사용한 것이다.
파이썬에서는 자료형도 각각의 클래스이다. type을 사용하면 객체(인스턴스)가 어떤 클래스 인지 확인할 수 있다.
34.1.3 인스턴스와 객체의 차이점
객체와 인스턴스는 같은 것이다. 보통 객체만 지정할 때는 객체라고 부르고, 클래스와 연관지어서 말할 때는 인스턴스라고 부른다.
빈 클래스 만들기
빈 클래스는 다음과 같이 코드 부분에 pass를 넣어주면 된다.
class Person:
pass
메서드 안에서 메서드 호출하기
메서드 안에서 메서드를 호출할 때는 self.메서드() 형식으로 호출해야 한다. self없이 메서드 이름만 사용하면 클래스 바깥쪽에 있는 함수를 호출한다는 뜻이 된다.
class Person:
def greeting(self):
print('hello')
def hello(self):
self.greeting()
특정 클래스의 인스턴스인지 확인하기
현재 인스턴스가 특정 클래스의 인스턴스인지 확인할 때는 isinstance함수를 사용한다. 특정 클래스의 인스턴스가 맞으면 True, 아니면 False를 반환한다.
isinstance는 주로 객체의 자료형을 판단할 때도 사용한다.
34.2 속성 사용하기
속성을 만들 때는 __init__메서드 안에서 self.속성 에 값을 할당한다.
class 클래스이름:
def __init__(self):
self.속성 = 값
class Person:
def __init__(self):
self.hello = 'hello! '
def greeting(self):
print(self.hello)
james = Person()
james.greeting()
__init__ 메서드는 james = Person() 처럼 클래스에 괄호를 붙여서 인스턴스를 만들 때 호출되는 특별한 메서드이다. __init__메서드는 인스턴스(객체)를 초기화 한다.
__init__처럼 앞뒤로 __(밑줄두개)가 붙은 메서드는 파이썬이 자동으로 호출해주는 메서드로 스페셜 메서드 또는 매직메서드 라고 부른다.
greeting메서드 에서는 print로 self.hello를 출력하였다.
Person으로 객체를 만들고, greeting를 호출하면 self.hello에 저장된 hello! 가 출력된다.
속성은 __init__메서드 안에서 만들고, self에 .(점)을 붙여서 할당한다. 클래스 안에서 속성을 사용할 때도 self에 .(점)을 붙여서 사용한다.
34.2.1 self의 의미
self는 인스턴스 자기 자신을 의미한다. 인스턴스가 생성될 때 self.hello처럼 자기 자신에 속성을 추가하였다.
위 클래스에서 __init__의 매개변수 self에 들어가는 값은 Person이다. self가 완성된 뒤에는 james가 할당된다. 이후 메서드를 호출하면 현재 인스턴스가 자동으로 매개변수 self에 들어온다. 그래서 greeting에서 self.hello의 속성을 출력할 수 있었던 것이다.
위 설명을 그림으로 나타내면 다음과 같다.
34.2.2 인스턴스를 만들 때 값 받기
다음과 같이 __init__메서드에서 self 다음에 값을 받을 매개변수를 지정하고, 매개변수를 self.속성에 넣어준다.
class 클래스이름:
def __init__(self, 매개변수1, 매개변수2):
self.속성1 = 매개변수1
self.속성2 = 매개변수2
다음은 Person 클래스로 인스턴스를 받을 때 매개변수로 이름, 나이, 주소를 받은 것이다.
class Person:
def __init__(self, name, age, address):
self.hello = 'hello!'
self.name = name
self.age = age
self.address = address
def greeting(self):
print('{} I am {}.'.format(self.hello, self.name))
maria = Person('maria', 20, 'seoul')
maria.greeting()
print(maria.name)
print(maria.age)
print(maria.address)
__init__메서드 에서는 매개변수로 name, age, address를 받고 각각 그대로 self에 넣어서 속성으로 만들었다.
greeting메서드는 인사를 하고, self.name으로 name 속성에 접근하여 이름을 출력하도록 하였다.
Person() 괄호 안에 이름, 나이, 주소 정보를 넣어 maria인스턴스를 만들었다. 괄호 안에 넣은 값은 __init__ 메서드의 self다음 매개변수로 차례대로 들어간다.
클래스 바깥에서 속성에 접근할 때는 인스턴스.속성 의 형식으로 접근이 가능하다. maria.name, maria.age등과 같은 방식으로 속성에 접근한다. 이렇게 인스턴스를 통해 접근하는 속성을 인스턴스 속성이라고 한다.
클래스의 위치인수, 키워드 인수
클래스로 인스턴스를 만들 때 위치 인수와 키워드 인수를 사용할 수 있다. 규칙은 함수와 동일하다. 위치인수와 리스트 언패킹을 사용하려면 다음과 같이 *args를 사용하면 된다. 매개변수에서 값을 가져오려면 args[0]과 같은 방식으로 사용해야 한다.
class Person:
def __init__(self, *args):
self.name = args[0]
self.age = args[1]
self.addr = args[2]
maria = Person(*['maria', 20, 'seoul'])
키워드 인수와 딕셔너리 언패킹을 사용하려면 **kwargs를 사용하면 된다. 매개변수에서 값을 가져오려면 kwargs['name']처럼 사용해야 한다.
class Person:
def __init__(self, **kwargs):
self.name = kwargs['name']
self.age = kwargs['age']
self.address = kwargs['addr']
maria1 = Person(name='maria', age=20, addr='seoul')
maria2 = Person(**{'name': 'maria', 'age': 20, 'addr': 'seoul'})
인스턴스를 생성한 뒤에 속성 추가하기, 특정 속성만 허용하기
다음과 같이 클래스로 인스턴스를 만든 뒤에 인스턴스.속성 = 값 의 형식으로 속성을 계속 추가할 수 있다.
이렇게 추가한 속성은 해당 인스턴스에서만 사용할 수 있다. 클래스로 다른 인스턴스를 만들면 추가한 속성은 없다.
__init__메서드가 아닌 다른 메서드에서도 속성을 추가할 수 있지만 이 경우 메서드를 호출해야 속성이 생성된다.
greeting메서드를 호출하기 전까지는 hello 속성이 없다.
특정 속성만 허용하고, 다른 속성들은 제한하고 싶을때 __slots__에 허용할 속성을 리스트로 넣어주면 된다. 속성 이름은 반드시 문자열 이여야 한다.
리스트에 들어있는 이름 외에 다른 이름을 가진 속성은 생성할 수 없다.
34.3 비공개 속성 사용하기
class Person:
def __init__(self, name, age, address):
self.hello = 'hello!'
self.name = name
self.age = age
self.address = address
위의 클래스에는 hello, name, age, address의 속성이 있고, 이 속성들은 메서드에서 self로 접근할 수 도 있고, 인스턴스.속성의 형식으로 클래스 밖에서도 접근할 수 있다.
클래스 안에서만 접근 가능하고, 밖에서는 접근할 수 없는 비공개 속성이 있다.
비공개 속성은 이름이 __(밑줄 두 개)로 시작해야 한다. 단, __속성__ 처럼 밑줄 두 개가 양 옆에 왔을 때는 비공개 속성이 아니다.
class 클래스이름:
def __init__(self, 매개변수):
self.__속성 = 값
다음은 Person클래스에 비공개 속성 __wallet을 넣은것이다.
class Person:
def __init__(self, name, age, address, wallet):
self.name = name
self.age = age
self.address = address
self.__wallet = wallet
maria = Person('maria', 20, 'seoul', 10000)
maria.__wallet -= 10000
위 코드를 실행하면 다음과 같은 에러가 발생한다.
__wallet는 비공개 속성이기 때문에 클래스 밖에서는 접근할 수 없다. __wallet에 접근하려면 다음과 같이 클래스 안에서 접근해야 한다.
class Person:
def __init__(self, name, age, address, wallet):
self.name = name
self.age = age
self.address = address
self.__wallet = wallet
def pay(self, amount):
self.__wallet -= amount
print('이제 {}원 남았네요'.format(self.__wallet))
maria = Person('maria', 20, 'seoul', 10000)
maria.pay(3000)
위 코드와 같이 비공개 속성은 클래스 안의 메서드에서는 접근할 수 있다.
보통의 프로그램에서는 지갑에 든 돈은 굳이 밝힐 필요가 없기 때문에 다음과 같이 돈이 얼마인지 확인하고, 모자라면 쓰지 못하는 식으로 만든다.
def pay(self,amount):
if amount > self.__wallet:
print('돈이 모자랍니다')
return
self.__wallet -= amount
비공개 메서드 사용하기
메서드도 이름이 __(밑줄 두 개)로 시작하면 클래스 안에서만 호출할 수 있는 비공개 메서드가 된다.
34.4 퀴즈
정답은 d이다.
정답은 __init__ 이다.
정답은 e이다.
정답은 c이다.
34.5 연습문제: 게임 캐릭터 클래스 만들기
정답은 다음 코드와 같다.
class Knight:
def __init__(self, health, mana, armor):
self.health = health
self.mana = mana
self.armor = armor
def slash(self):
print('베기')
34.6 심사문제: 게임 캐릭터 클래스 만들기
정답은 다음 코드와 같다.
class Annie:
def __init__(self, health, mana, ability_power):
self.health = health
self.mana = mana
self.ability_power = ability_power
def tibbers(self):
print('티버: 피해량 {}'.format(self.ability_power * 0.65+400))
'Project H4C Study Group' 카테고리의 다른 글
[Project H4C] 코드업 기초 100제 (1) (0) | 2021.02.02 |
---|---|
[Project H4C] 파이썬 코딩도장(12) (0) | 2021.01.31 |
[Project H4C] 파이썬 코딩도장(10) (0) | 2021.01.29 |
[Project H4C] 파이썬 코딩도장(9) (0) | 2021.01.28 |
[Project H4C] 파이썬 코딩도장(8) (0) | 2021.01.26 |