1. 함수 선언

1
2
3
4
5
6
7
8
9
10
11
12
a=3
b=5

def func1(param1, param2):
    global a
    a=5
    b=6
    return param1 * param2 * b

result = func1(3, 2)

print(a) # 5가 출력된다.

- 함수 내 전역변수 사용: 이 경우 굳이 함수 내에서 이를 캡쳐하겠다고 특별한 선언을 해야 하는 것은 아니며 그러한 선언 없이도 자유롭게 사용이 가능하다. 단, 이 경우 함수 내부에서 전역변수의 내용을 변경하는 것은 불가능하다. (대입식을 쓰는 경우라면 에러가 발생하지는 않지만, 이름이 같은 새 지역변수를 선언하는 것으로 취급된다. 따라서 그 대입 결과가 함수 외부에 전달되지 않는다.) 이 경우 함수 내부에서 global 예약어를 사용하여 전역변수를 선언하면, 함수 내부에서 그 변수의 값을 바꿀 수 있고 또 그 결과가 함수 외부에 전달된다.

2. 람다식

1
2
3
4
5
l_func1 = lambda param1, param2: param1 * param2
print(l_func1(2, 3))

l_func2 = lambda: 15
print(l_func2())

- 함수 이름을 쓰지 않고 함수를 선언하는 표현을 람다식(lambda expression)이라 하며, 상기한대로 그 내용을 변수에 담아 그 변수 이름을 그 람다 함수의 이름으로 쓸 수도 있고 람다식 자체를 또 다른 함수 호출 시 파라미터로 전달할 수도 있다.

- 파이썬의 람다식은 람다식을 뜻하는 예약어 lambda와 파라미터 선언, :으로 구성된다.

  • 일반적인 함수와 달리 람다식의 함수 내용은 오로지 콜론 뒤에만 쓸 수 있으며, 구문 단 하나만 쓸 수 있다.

  • 람다식의 함수 내용으로 작성한 구문이 리턴하는 값이 그대로 그 람다식이 리턴하는 함수값이 되며, return 같은 예약어를 필요로 하지 않는다. (return 예약어를 사용하면 오히려 에러가 난다.)

* call by value, call by reference

- 파이썬의 함수 호출 시 전달되는 인자가 mutable 객체(list, dict 등 이를 구성하는 원소의 값을 변경하더라도 그 변수명이 지정하는 주소값이 변하지 않는 객체)인지 immutable 객체(int, str, tuple 등 값을 재정의하면 그 객체를 담고 있던 변수명이 지정하는 주소값이 달라지는 객체)인지에 따라 행동 양상이 call by value에 가까운지 call by reference에 가까운지가 달라진다.

  • 인자가 immutable 객체: 함수 내에서 값을 변경하더라도 그 변경사항이 그 함수를 호출한 영역에 반영되지 않는다. (call by value처럼 행동한다.)

  • 인자가 mutable 객체: 함수 내에서 값을 변경할 경우 그 변경사항이 곧 그 함수를 호출한 영역에도 반영된다. (call by reference처럼 행동한다.)

- 따라서 함수로 전달받은 파라미터를 call by value 또는 call by reference처럼 사용하고 싶다면 그 객체가 mutable 객체인지 immutable 객체인지를 확인한 후 이를 코딩에 반영해야 한다.

  • mutable 객체를 파라미터로 전달받았으나 이를 call by value처럼 사용하고 싶다면, 함수 호출 후 빈 객체를 새로 선언한 후 이 안에 파라미터로 전달받은 객체를 복사해 사용해야 한다.

  • immutable 객체를 파라미터로 전달받았으나 이를 call by reference처럼 사용하고 싶은 경우 다음 두 방법이 있다.

(1) 전역변수로 선언 후 함수 내에서 global 선언을 할 수 있다.

(2) 변경된 결과값을 리턴값으로 해서 함수 호출 때 해당 객체를 그 리턴값으로 재정의하는 방법이 있다.