26.8.13 / Thu

BaO·2026년 8월 13일

TIL

목록 보기
3/33

5-2 변수 스코프 & 람다 함수

  • 변수 스코프(Scope) : 변수를 접근할 수 있는 범위

1. 전역 (Global) & 지역 변수 (Local)

  • 전역 변수 : 함수 외부에 정의된 변수, 코드 전역에서 접근 가능
  • 지역 변수 : 함수 내부에 정의된 변수, 함수가 실행중일 때만 유효함.
a = 10 # 전역

def func() :
    b = 20 # 지역
    print(a , b)

# print(a,b) -> name 'b' is not defined 오류
func()
c = 30

def outer() :
    a = 10
    # print('b', b)
    def inner() :
        b = 20
        print(f'{a=} {b=} {c=}')

    inner()

outer()

2. 파이썬 변수 검색 규칙 : LEGB 스코프

  • L (local : 지역) > E (enclosing : 외부 함수) > G (global : 전역) > B(builtin : 내장)
a = 'Global'
def outer() :
    a = 'Enclosing'
    print('outer: ' a)
    def inner() :
        a = 'Local'
        print('inner: 'a)

3. global 키워드

a = 'Global'
def outer() :
    a = 'Enclosing'
    print('outer: ', a)
    def inner() :
        global a # a라는 변수는 전역변수를 찾겠다.
        a = '000'
        # 전역변수의 값을 변경할 수 있기 때문에 문제가 발생할 수도 있음
        print('inner: ',a)
    inner()
outer()

4. 일급 함수 (First-Class Function)

  • 함수와 변수를 동일하게 취급
  • 함수의 매개변수로 함수를 사용할 수 있다 : 콜백 함수
  • 함수의 반환값으로 함수를 사용할 수 있다 : 팩토리 함수, 클로저
def callback2() :
    print('callback()')

def func(callback) :
    print('func()')
    callback()
    # 외부 함수를 호출해서 사용하는 것을 callback 함수라고 함.

func(callback2)
def outer(num1):
    def inner(num2):
        return 10 + num2

    return inner

a = outer(10) # -> num1은 10으로 고정된 inner 함수명을 가지고 있음
print(a(20)) # 30 -> num2를 20으로 선언하여 10 + 20이 됨
print(a(100)) # 110 -> num2를 100으로 선언하여 10 + 100이 됨
  • 정상적인 함수 동작
  • return한 inner 함수에서 계속 num1을 사용하기 때문에

    num1을 함수 종료시에 자원이 해제되는 콜 스택이 아닌

    힙 영역에 저장하면서 num1은 10으로 고정된다(클로저)

5. lambda 함수

  • 함수를 일회용으로 사용하는 경우 한줄의 식으로 간단하게 함수 정의
  • 일회용으로 사용되기 때문에 매개변수 이름도 최대한 간결하게 한글자로 선언
lambda 매개변수1, 매개변수2 : 처리 부분

square = lambda num: num ** 2

square(10)
def change_numbers(callback, *args):
    numbers = list(args)

    for i in range(len(numbers)):
        numbers[i] = callback(numbers[i])

    return numbers

# change_numbers(lambda num: num ** 2, 10, 20, 30)
change_numbers(lambda x: x ** 2, 10, 20, 30)

6. 전역 변수와 지역 변수의 이름 충돌과 은닉 법칙

7. lmabda, map(), filter()을 활용한 데이터 일괄 제공

  • map() : 변환 작업
  • filter() : 특정 조건에서 데이터 선별
fruits = ['사과', '오렌지', '망고']
result = list(map(lambda x: f'**{x}**', fruits))

print(result)
numbers = [*range(1, 11)] # 1 ~ 10

print(list(filter(lambda x : x % 2 == 1, numbers)))

5-3 클로저 & 데코레이터

1. 파이썬 함수의 일급 객체 특성과 고차함수

2. 클로저(Closure)

def outer():
    num1 = 10
    def inner():
        num2 = 20
        print(num1 + num2)

    return inner

inner = outer() # num1은 inner에 의해서 사용되므로 힙 영역에 생성되어 있다.
inner()
  • 고차 함수 (Higher Order Function)
def add(num1):
    def _add(num2):
        def __add(num3):
            return num1 + num2 + num3

        return __add
    return _add

a = add(10)
b = a(20)
c = b(30)
print(c)

print(add(10)(20)(30))
add10 = add(10)
print(add10(30)(40))
add10_20 = add(10)(20)
print(add10_20(30))

3. 데코레이터(Decorator)

  • 디자인 패턴 중 한가지
def factorial1(num):
    result = 1
    for i in range(1, num+1):
        result *= i

    return result

factorial1(5)
# 재귀 함수 (Recursive) - 함수 내에서 같은 함수를 반복해서 호출하는 방법
def factorial2(num):
    if (num < 1):
        return 1

    return num * factorial2(num - 1) # 재귀함수

factorial2(5)
# 핵심 기능과 공통 기능의 분리, 핵심 기능을 원하는 함수로 변경 가능
def time_checker(callback, num):
    start = time.time() # 공통 기능

    result = callback(num)
    # 핵심 기능 - 팩토리얼 연산 함수 (factorial1, factorial2)

    end = time.time() # 공통 기능
    print("총 소요 시간: " , end - start)

    return result

print('결과 값 : ', time_checker(factorial2, 10))
# python 제공하는 데코레이터 적용법

def time_checker2(callback):

    def wrapper(num):
        start = time.time() # 공통 기능

        result = callback(num) # 핵심 기능

        end = time.time() # 공통 기능
        print('소요 시간 : ', end - start) # 공통 기능

        return result

    return wrapper

@time_checker2 # 자동으로 factorial2 함수 인식
def factorial2(num):
    if (num < 1):
        return 1
    return num * factorial2(num - 1)

factorial2(10)
# factorial2 함수를 실행했을때 자동으로 time_checker2 함수로 넘김


@time_checker2
def add(num1, num2):
    return num1+num2

print(add(10, 20))

# time_checker안의 warrap함수의 매개변수가 1개이기 때문에 오류 발생함.
# 매개변수의 숫자를 add와 동일시 하면 정상 작동한다.
# 이 문제를 해결하기 위해서 wrapper의 매개변수를 가변으로 선언한다.

def time_checker2(callback):

    def wrapper(*args):
        start = time.time() # 공통 기능

        result = callback(*args) # 핵심 기능

        end = time.time() # 공통 기능
        print('소요 시간 : ', end - start) # 공통 기능

        return result

    return wrapper

# wrapper의 매개변수를 가변으로 적용함으로써 각 함수마다 매개변수의 개수가 다른 경우에 발생하는 문제를 유동적으로 적용할 수 있다.
# 하지만 가변 인수만 적용했을때에는 키워드 가변 인수를 적용할 수 없다.
# 이를 해결하기 위해서 가변 인수와 키워드 가변 인수 두 개 모두 적용한다.

def time_checker2(callback):

    def wrapper(*args, **kwargs):
        start = time.time() # 공통 기능

        result = callback(*args, **kwargs) # 핵심 기능

        end = time.time() # 공통 기능
        print('소요 시간 : ', end - start) # 공통 기능

        return result

    return wrapper
DQ
# 함수 이름만 작성하고 이후에 코드 작성할 때
def add() : pass

0개의 댓글