Pyhon에서 조건문은 if를 쓴다. if 다음에 오는 조건이 True면 그 아래 코드를 실행하고 False면 넘어간다. 그렇다면 Python에서는 True False를 어떻게 판단할까?
Python에서는 Tyue와 False를 존재론 적 관점에서 판단한다 아래 몇 가지 예시를 보자
# if 3이 왜 참일까??
if 3:
print('a')
else:
print('b')
# if 0은 왜 거짓일까?
if 0:
print('a')
else:
print('b')
# 이건 왜 참일까?
if [1]:
print('a')
else:
print('b')
# 이건 왜 거짓일까?
if []:
print('a')
else:
print('b')
# 이건 왜 거짓일까?
if str():
print('a')
else:
print('b')
# 이건 왜 거짓일까? => 값이 없다는 뜻이니까 False
if None:
print('a')
else:
print('b')
if ['']: # 얘는 없는 것('')을 가지고 있으니까 True!
print('a')
else:
print('b')
Python의 모든 데이터 타입은 True/False를 판단할 수 있고, 그 판단은 존재론적인 관점에서 수행된다. 그렇다면 어떤 것이 존재하느냐가 기준이 될까? 바로 원소의 존재이다.
[1]은 원소가 있으므로 True이다. 하지만 []는 원소가 없으므로 False이다. 'a'는 a가 있으므로 True이지만 ''는 아무 원소도 없으므로 False이다. 10은 10이라는 어떤 수가 존재하여 True지만, 0은 수가 없다(=존재하지 않는다)는 뜻이므로 False이다.
Python은 True와 False를 존재론적 관점에서 판단한다.
True/False를 가장 잘 사용하는 예시를 들자면 반드시 and와 or가 나온다. 그렇다면 and와 or은 어떻게 동작할까? 아래 예시를 보자
'' and 10
'a' and 10
'' or 10
'a' or 10
위 결과는 아래와 같다.
''
10
10
'a'
왜일까? and는 앞에 오는 요소가 True면 뒤에 있는 요소를 반환하고, False면 앞에 있는 요소를 반환한다. or은 그 반대이다. or은 앞에 오는 요소가 True면 앞에 있는 요소를 반환하고, True면 뒤에 있는 요소를 반환한다.
신기한 점은 python은 short circuit 기술을 제공한다. 앞에서 그 결과가 결정되면 뒤에 있는 요소는 계산하지 않고 실행을 중단한다. 그래서 아래와 같은 코드도 에러 없이 작동한다.
3 or 1/0
or은 앞에 요소가 True면 그것을 반환한다고 했는데, 3은 True이므로 이미 이 결과가 True로 축약됐다. 따라서 1/0은 계산하지 않기 때문에 에러가 발생하지 않는다. 또 중요한 점은 True와 False는 어떤 결과를 하나의 결과로 축약하기 때문에 식(expression)이고, a = 1
에서 1 자리에 올 수 있다.(1일차 내용 참고)
if 조건문을 expression으로 사용할 수 있다.
>>> a = 0
>>> 1 if a == 1 else 2 if a == 2 else 3
3
한 줄로 사용 가능하고, 하나의 결과값으로 축약되므로 식(expression)이다. 따라서 a = 1
에서 1 자리에 올 수 있다.(1일차 내용 참고)
python에서는 iterable이라는 개념이 있다. 어떤 객체를 dir() 했을 떄 __iter__ 가 있으면 iterable이다. iterable은 iterator가 될 수 있는 것들을 의미하고, iterator는 메모리에서 원소를 하나씩 뽑아낼 수 있는 객체를 의미한다. iterable은 객체로 선언되는 순간 iterator가 된다.
Python에는 수 많은 iterable이 있는데, 사실 container는 모두 iterable이다. 예를 들면 sum, all, any, list, '문자열' 등이 있다.
for문에서 in 뒤에는 iterable이 위치하는데, for문이 어떻게 동작하는지 확인할 수 있다.
# 실제로 for문이 어떻게 동작하는지 확인해보자
def f():
for i in [1, 2, 3, 4]:
print(i)
import dis
dis.dis(f)
for문에서도 else를 사용할 수 있다.(else는 조건문, 반복문, 예외처리문에서 사용됨) 반복문에서 else는 break되지 않으면 실행된다.
# continue와 break를 바꿔가며 실습해보기
for i in [1, 2, 3, 4]:
if i == 3:
continue
# break
print(i)
else:
print('end')
Python에서 미리 지정되어있는 예약어는 총 36개인데, 그 중 6개가 예외처리와 관련되어있다. 그만큼 Python은 에러나 예외처리가 잘 구현되어있음을 알 수 있다.
# 참고 - 키워드 확인
import keyword
keyword.kwlist
예외처리를 하는 목적은 두 가지가 있다.
assert 뒤에는 True/False가 온다. 뒤에 오는 것이 False면 AssertError를 발생한다.
# 에러 없음
a = 1
assert a == 1
# 에러 발생
assert a == 2, '추가 설명은 이렇게 쓴다.'
raise는 강제로 에러를 발생시킨다. Exception 클래스를 상위 클래스로 상속받아서 만들어진다.
# raise는 발생시키고 싶은 에러를 써준다.
raise ZeroDivisionError
# try 부분에 에러 발생 시 except 부분 실행, try 부부에 에러 발생하지 않으면 else 부분 실행
# finally는 언제나 실행
# try, except는 필수 / else, finally는 옵션
try:
# 1/0
1
except error_msg:
print(error_msg)
else:
print('no error')
finally:
print('just do it')
Python에는 callable이라는 개념이 있다. 바로 괄호가 붙을 수 있는 것들에 대한 개념인데, callable 개념이 적용되는 대상은 함수, method, class, generator이다. 오늘은 이 중 함수의 기초적인 부분에 대해 알아보도록 하자.
함수란 여러 동작을 묶어서(=캡슐화) 재활용 할 수 있게 만든 것이다. 같은 동작을 여러번 반복하여 사용하기 위해서이다. 재활용할 필요가 없는 함수(=이름을 붙일 필요가 없는 함수)는 lambda 함수이다.
함수를 공부할 때 parameter(매개변수)와 argument(인자)를 잘 구분해야 한다. 아래와 같은 차이가 있다.
def func(x):
return x
func(4)
'''
func -> 매개이름
x -> parameter
4 -> argument
'''
위에서 함수 func은 매개이름, x를 매개변수라고 한다. 매개이름과 매개변수를 합쳐서 signiture라고 한다.
함수는 항상 input과 output을 가지고, output은 return 값이다. 그런데 생각해보면 Python에서는 output이 없는 함수도 있다. list.append('somthing')처럼 말이다. return 값이 없는 함수에는 Python에서 return None
을 추가해 컴파일한다. 따라서 return값이 없다고 값이 바뀌지 않는 것은 아니다!
함수를 사용할 때에는 2가지 방법이 있다. positional 방식과 keyword 방식이다. positional 방식은 매개변수를 선언한 순서대로 사용하는 방법이고, keyword 방식은 매개변수 이름을 직접 불러서 사용하는 방법이다.
def test(a, b, c):
return a + b + c
# positional
test(1, 2, 3)
# keyword
test(a=1, b=2, c=3)
positional 방식과 keyword 방식은 혼용해서 사용할 수 있는데, keyword 방식이 사용된 후에는 반드시 모든 인자는 keyword 방식으로 지정되어야 한다.
test(1, b=2, c=5)
test(1, b=2, 2) # 에러 발생
parameter에는 default 값을 지정할 수 있다.(=default technique) 매우 편리한데, 모두 defualt 값으로 넣어두고 필요한 parameter만 keyword 방식으로 변경할 수 있기 때문이다.
>>> def de(a, b, c=4):
return a + b + c
>>> de(1, 2)
7