[패스트캠퍼스python] 파이썬 함수식

파이썬 인강 : 파이썬 함수식

함수식과 람다에 대해 자세히 알아보자.
우리가 함수를 사용하는 이유는 반복적이고 중복되는 프로그램을 방지하기위해서다

1. 함수 정의 방법

아래처럼 하면 끝!

1
2
def 함수명(parameter):
code작성하기

여기서 def는 define의 약자이다.

함수를 호출하는 방법은 함수명() 이고 만약 parameter가 있다면 함수명(parameter)로 호출하면 된다

1
2
3
4
5
6
7
def hello(world):
print("Hello, ", world)

hello("Python!")

# 출력값은
Hello, Python!

2. 함수 선언 위치

함수를 선언할때는 선언 위치가 매우 중요하다
파이썬은 항상 위에서부터 아래로 실행되기 때문이다
위의 예제에서 아래 사진처럼 선언 위치를 바꾸면 터미널에 NameError 뜨는 것을 볼 수 있다
hello라는 이름이 정의되어 있지 않다는 에러이다.

리턴이라는 예약어를 통해서 함수를 출력할수도있다
아래 예제를 보자
항상 형변환을 주의하자

1
2
3
4
5
6
7
8
9
def hello_return(world):
value = "Hello, " + str(world)
return value

str = hello_return("천사!")

print(str)
# 출력값은
Hello, 천사!

3. 다중리턴

다중리턴을 사용하면 짜임새있는 함수를 만들 수 있다.
java나 기타언어들은 return값이 하나인 게 원칙인데 파이썬은 다르다
파이썬은 다중리턴을 허용한다

1
2
3
4
5
6
7
8
9
10
11
12
def func_mul1(x):
y1 = x * 2
y2 = x * 4
y3 = x * 6
return y1, y2, y3

val1, val2, val3 = func_mul1(10)

print(val1, val2, val3)

# 출력값은
20 40 60

파이썬의 매력적인 부분은 return값의 데이터 타입 변환이다.
왜냐면 엄청 간단하고 쉽기때문에
위의 예제에서 return의 데이터형태는 int(정수)이다.
만약 데이터형태를 int가 아닌 다른 형태로 나타내고 싶다면 어떻게 하면 될까?

만약 데이터형태를 리스트로 받고싶다면 return[y1, y2, y3]를 적어주면 끝!
만약 튜플로 받고싶다면 return(y1,y2, y3)로 하면 끝!
만약 딕셔너리로 return받고싶다면?

1
2
3
4
5
6
7
8
9
10
11
12
13

def func_mul3(x):
y1 = x * 2
y2 = x * 4
y3 = x * 6
return {'ret1': y1, 'ret2': y2, 'ret3': y3}

dic = func_mul3(8)

print(type(dic), dic, dic.get('ret3'), dic.items(), dic.keys(), dic.values())

# 출력값은
<class 'dict'> {'ret1': 16, 'ret2': 32, 'ret3': 48} 48 dict_items([('ret1', 16), ('ret2', 32), ('ret3', 48)]) dict_keys(['ret1', 'ret2', 'ret3']) dict_values([16, 32, 48])

정말 저세상 간단함!
정말 매력적인 언어다!

4. *args, **kwargs 이해

  1. *args (아스타)
    arguments의 약자로 가변인자(인자의 갯수가 변할 수 있음)를 뜻한다
    다양한 매개변수를 받아서 함수의 흐름이 바뀌게한다
    매개변수를 하나를 넣든 세개를 넣든 튜플의 형태로 출력해준다
    기본적으로 *args라고 적지만 이 매개변수명은 자유롭게 변경 가능하다
    enumerate는 순회라는 의미로 index를 넣어서 나타낼 수 있다. 꼭 알아두자
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def args_func(*args):  # 매개변수명 자유롭게 변경 가능
for i, v in enumerate(args):
print(v, i)

args_func('비')
args_func('비', '보')
args_func('비', '보', 'TV')

# 출력값은
0
0
1
0
1
TV 2

만약 출력값을 여러줄 나오는게 싫다! 한 줄로 나타내고 싶다면?
print(v, i)를 print(‘{}’.format(i), v, end=’ ‘)로 바꿔주면 된다

1
2
# 출력값은
0 비 0 비 1 보 0 비 1 보 2 tv

만약 *argsrange()를 같이 사용하면 어떻게 될까?

1
2
3
4
5
6
7
8
9
def args_range(*args):  
for i, v in enumerate(range(3)):
print(i,v)
args_range()

# 출력값은
0 0
1 1
2 2
  1. kwargs
    args와 똑같은 가변인자이나 딕셔너리로 받는다는 차이점이 있다.
    별표가 하나일때는 튜플로 받는데 별표가 두개인경우 딕셔너리로 받는다.
    위의 args와 마찬가지로 매개변수명은 자유롭게 변경 가능하다
1
2
3
4
5
6
7
def kwargs_func(**kwargs):  # 매개변수명 자유롭게 변경 가능
print(kwargs)
kwargs_func(name1='가')
kwargs_func(name1='가', name2='나')
# 출력값은
{'name1': '가'}
{'name1': '가', 'name2': '나'}

딕셔너리형태말고 한 줄에 주르륵 출력하고 싶으면
print(kwargs)를 print(‘{}’.format(v), kwargs[v], end=’ ‘)로 바꿔주면 된다

1
2
# 출력값은
name1 가 name1 가 name2 나
  1. *args*kwargs의 혼합
    효율적인 코딩을 위해 필수이며 꼭 이해를 해야하는 부분이다

아래 터미널처럼 가변인자(args와 kwargs)는 없이 int 10과 20만을 넣어도 출력이 되는 것을 알 수 있다.
가변인자는 값이 없기때문에 빈 튜플과 빈 딕셔너리가 출력된다.

1
2
3
4
5
6
7
def example(arg_1, arg_2, *args, **kwargs):
print(arg_1, arg_2, args, kwargs)

example(10, 20, 'park', 'kim', age1=77, age2=80 )

# 출력값은
10 20 ('park', 'kim') {'age1': 77, 'age2': 80}

실습을 하면서 궁금했던 점은 어떻게 튜플과 딕셔너리를 나누는 지 궁금했는데 완전 초보적인 생각이었다
딕셔너리형태인 address=뭐시기를 넣으면 자동적으로 **kwargs 로 출력된다.
만약 딕셔너리 형태를 순서를 섞어 놓으면

1
example(10, 20, address="Busan", 30, 'park', age1=77, age2=80 )

아래 이미지와 같이 SyntaxError가 발행한다.

SyntaxError

전체적으로 쉽게 설명한 참고링크1

5. 중첩함수

말그래도 함수안에 함수가 있는 것
중첩함수를 잘해둬야 클로저를 잘 해결할 수 있다
클로저를 나아가서 Python decorator도 중급자에서 필수적인 내용이니 꼭 이해하자

1
2
3
4
5
6
7
8
9
10
11
12
def nested_func(num):
def func_in_func(num):
print('언제실행될까? ', num)

print("함수 안에서")
func_in_func(num + 100)

nested_func(1)

# 출력값은
함수 안에서
언제실행될까? 101

혹시 함수안의 함수 func_in_func()를 실행시킬 수 있을까?

1
func_in_func(1)

정답은 실행불가!
아래 이미지처럼 Name Error가 발생한다

Name Error