Python 함수에서 global과 nonlocal의 활용과 고급 함수 개념 이해

global과 nonlocal 키워드 사용법

global은 함수 내부에서 전역 변수를 수정할 때 사용하고, nonlocal은 중첩 함수에서 상위 함수의 변수를 수정할 때 사용합니다. nonlocal은 전역 범위에서는 사용할 수 없습니다.

# global 예시
total = 100

def update_total():
    global total
    total = 200

update_total()
print(total)  # 200
# nonlocal 예시
def outer_func():
    value = 10

    def inner_func():
        nonlocal value
        value = 20

    inner_func()
    print(value)  # 20

outer_func()

함수 객체 (함수명)

함수는 Python에서 일급 객체입니다. 따라서 변수에 할당하거나, 컨테이너에 저장하거나, 인자로 전달하거나, 반환값으로 사용할 수 있습니다.

함수를 참조하기

def greet():
    return 'Hello'

def caller():
    return greet()

print(caller())  # Hello

함수를 컨테이너 요소로 사용하기

def add(a, b):
    return a + b

def multiply(a, b):
    return a * b

operations = {'+': add, '*': multiply}
print(operations['+'](3, 4))  # 7

함수를 인자로 전달하기

def execute(func, x, y):
    return func(x, y)

result = execute(add, 5, 3)
print(result)  # 8

함수를 반환하기

def get_adder():
    def adder(a, b):
        return a + b
    return adder

my_adder = get_adder()
print(my_adder(10, 20))  # 30

함수의 중첩 호출

함수 내부에서 다른 함수를 호출할 수 있습니다. 이는 함수가 일급 객체이기 때문에 가능합니다.

def helper():
    return 'Helper called'

def main():
    return helper() + ' from main'

print(main())  # Helper called from main

함수의 중첩 정의

하나의 함수 내부에서 여러 개의 함수를 정의하고 조건에 따라 호출할 수 있습니다.

user_database = []

def process_user(action_type):
    def register():
        user_id = input('사용자 ID 입력: ').strip()
        for record in user_database:
            if user_id == record['user_id']:
                print('이미 존재하는 ID입니다')
                return
        name = input('이름 입력: ').strip()
        age = input('나이 입력: ').strip()
        salary = input('급여 입력: ').strip()
        new_user = {'user_id': user_id, 'name': name, 'age': age, 'salary': salary}
        user_database.append(new_user)
        print(f'{name} 사용자 추가 성공')

    def remove():
        target_name = input('삭제할 사용자 이름 입력: ')
        for idx, record in enumerate(user_database):
            if record['name'] == target_name:
                user_database.pop(idx)
                print('삭제 완료되었습니다')
                return
        print('해당 사용자를 찾을 수 없습니다')

    if action_type == 1:
        register()
    elif action_type == 2:
        remove()
    else:
        print('잘못된 입력입니다')

process_user(1)
process_user(2)

클로저 함수

클로저는 내부 함수가 외부 함수의 변수에 접근할 수 있는 함수입니다. 이를 통해 기존 로직을 변경하지 않고 새로운 기능을 추가할 수 있습니다. 외부 함수의 인자를 내부 함수가 참조할 때 클로저가 형성됩니다.

def power_generator(exponent):
    def power(base):
        return base ** exponent
    return power

square = power_generator(2)
cube = power_generator(3)

print(square(5))   # 25
print(cube(5))     # 125

클로저의 핵심은 내부 함수가 외부 함수의 스코프에 있는 변수를 기억하고 있다는 점입니다. 위 예제에서 squarecube는 각각 exponent 값 2와 3을 기억하고 있습니다.

6월 20일 17:36에 게시됨