1. 변수의 범위
변수의 범위(scope)는 해당 변수를 프로그램 안에서 어디까지 참조하고 사용할 수 있는지를 의미한다.
파이썬에서는 변수가 선언된 위치에 따라 사용할 수 있는 범위가 달라진다.
1.1 지역 변수
- 가장 내부의 범위로 함수 내에서 정의된 변수들이 지역 변수에 해당된다.
- 함수 안에서 만들어진 변수는 그 함수 안에서만 사용할 수 있다.
예시

👉 위 코드에서 local_var는 local_example() 함수 안에서 만들어진 변수이다.
따라서 함수 안에서는 정상적으로 사용할 수 있지만, 함수 밖에서 local_var를 사용하려고 하면 오류가 발생한다.
1.2 전역(글로벌) 변수
- 스크립트 전체에서 사용되는 범위로, 함수외부에서 정의된 변수가 해당된다
- 모든 함수에서 접근할 수 있지만, 함수 내부에서 수정하려면
global키워드가 필요하다
예시 1

👉 global_var 은 전역변수이다.
👉그래서 test_global_scope() 함수 안에서도 접근할 수 있고, 함수 밖에서도 그대로 사용할 수 있다.
예시 2 – 전역변수와 지역 변수의 이름이 같을 때

👉 global_var=10 ⇨전역변수
👉 modify_global() 함수 안의 global_var=20 ⇨ 전역 변수의 값을 바꾼 것이 아니다.
함수 안에서 같은 이름의 지역 변수를 새로 만든 것이다
👉 그래서 함수 안에서는 20이 출력되고, 함수 밖에서는 원래 전역 변수 값인 10이 그대로 출력된다.
예시 3 – global 키워드
만약 함수 안에서 전역 변수의 값을 직접 수정하고 싶다면 global 키워드를 사용해야 한다.

👉 global global_var라고 작성하면, 함수 안에서 사용하는global_var가 지역 변수가 아니라 전역 변수라는 뜻이 된다.
👉 그래서 함수 안에서 global_var = 20을 실행하면 실제 전역 변수의 값이 바뀐다.
✔️ 함수 안에 함수가 들어 있는 구조
파이썬에서는 함수 안에 또 다른 함수를 정의할 수 있다.

👉 여기서 outer_function() 안에 inner_function()이 들어 있다.
👉 그리고 inner_function()은 바깥 함수인 outer_function()의 변수 enclosing_var를 사용하고 있다.
👉 위 코드를 실행하면 outer_function()은 내부 함수인 inner_function 자체를 반환한다.
👉 그래서 f에는 inner_function이 저장되고, f()를 실행하면 내부 함수가 실행된다.
👉 이때 outer_function()의 실행은 이미 끝났는데도, inner_function()이 여전히 enclosing_var를 기억하고 있다.
✅ 클로저 공간
클로저 공간은 `내부 함수가 외부 함수의 변수를 계속 사용할 수 있도록, 그 값을 따로 저장해두는 메모리 영역(객체 구조)이다.
일반적으로 함수가 끝나면 그 안의 지역 변수는 사라진다.
하지만, 내부 함수가 그 변수를 참조하고 있으면 파이썬은 해당 값을 지우지 않고 함수 객체 안에 __closure__라는 형태로 보관한다.
이때 저장되는 값은 보통 cell 객체로 감싸져 유지되며, 내부 함수는 실행될 때 이 클로저 공간을 통해 외부 변수에 접근할 수 있다.
🔸 빌트인 함수
- 파이썬에서 별도의
import 없이바로 사용할 수 있도록 기본적으로 제공되는 함수들 - ex)
print(),len(),type(),range() - 파이썬이 실행될 때 자동으로
Built-in 네임스페이스에 등록되어 있기 때문에 이름만으로 호출할 수 있다
✅ 빌트인 함수 이름을 함부로 변수로 사용하면 안되는 이유
파이썬에서는 빌트인 함수 이름도 변수 이름처럼 사용할 수 있다.
하지만 그렇게 하면 원래 함수가 가려질 수 있다.
len = 5 # 내장 함수 'len'을 덮어씀
#print(len([1, 2, 3])) # 오류 발생!
👉 위 코드에서 len이라는 이름에 숫자 5를 넣어버렸기 때문에, 파이썬은 더 이상 len을 함수로 보지 않는다.
그래서 len([1, 2, 3])처럼 사용하면 오류가 발생한다.
또한, str 같은 이름도 가능하면 변수명으로 사용하지 않는 것이 좋다.
✅ LEGB 규칙
빌트인 함수는 변수 이름을 찾을 때 적용되는 LEGB 규칙의 마지막 단계에 해당한다.
LEGB 규칙이란 파이썬에서 변수를 찾을 때 정해진 순서대로 이름을 검색하는 규칙이다.
즉, 파이썬은 이름을 찾을 때 가까운 범위부터 순서대로 탐색한다고 이해할 수 있다.
Local(지역변수)
→ Enclosing(둘러싸인, 함수 안의 함수)
→ Global(전역 변수)
→ Built-in(빌트인 함수)
따라서 위의 예시처럼 같은 이름의 변수를 직접 정의하면 기존 빌트인 함수가 가려질 수 있다는 것이다.
4. 함수 메모리 제거
함수도 파이썬 객체이므로 참조 카운팅과 가비지 컬렉션의 원칙에 따라 동작한다.
함수를 참조하는 이름(변수)이 더 이상 없으면, 해당 함수 객체는 가비지 컬렉션 대상이 될 수 있다.
del 명령어를 사용하여 함수에 대한 참조를 명시적으로 제거할 수 있지만 이것이 곧 함수가 즉시 메모리에서 제거된다는 것을 보장하지는 않는다.
def func1():
print('처음으로 만드는 함수')
del func1
# 이후 func1()을 호출하려고 하면 오류가 발생함
func1()
실행 결과

5. 콜백 함수 (⭐️⭐️⭐️⭐️⭐️)
콜백 함수(callback function)는
다른 함수에 인자로 전달되어, 특정 시점이나 조건이 되었을 때 나중에 호출되는 함수를 의미한다.
파이썬에서는 함수도 객체이기 때문에 변수처럼 전달할 수 있다.
따라서, 이를 활용해 특정 시점에 실행할 동작을 미리 정의해둘 수 있다.
즉, 콜백 함수는 “지금 바로 실행하는 함수”가 아니라, 다른 함수에게 맡겨두었다가 필요할 때 호출되도록 하는 함수이다.
예시 1

👉
execute(say_hello)
이 코드는 say_hello()를 실행하는 것이 아니다. 함수 자체를 전달한 것이다.
예시 2
def print_score(score):
print(f'score : {score}')
def print_pass_fail(score):
if score >= 80:
print(f"{score}점: 합격")
else:
print(f"{score}점: 불합격")
def process_scores(scores,callback):
for score in scores:
callback(score)
def print_bonus_score(score):
print(f"보너스 적용 점수 : {score + 5}")
scores = [80, 95, 70, 100, 60]
print("원점수 출력")
process_scores(scores,print_score)
print("합격,불합격 출력")
process_scores(scores,print_pass_fail)
print("==보너스 점수 출력==")
process_scores(scores,print_bonus_score)
실행 결과

👉
process_scores(scores,print_score)
process_scores(scores,print_pass_fail)
process_scores(scores,print_bonus_score)
여기서 process_scores에 순서대로 print_score → print_pass_fail -> print_bonus_score 함수들을 인자로 전달한 것이다.
예시 3
콜백 함수 개념은 sorted()에서도 자주 등장한다.
예를 들어 dict으로 저장된 학생 정보 관련 리스트를 점수 기준으로 정렬한다고 해보자.
students = [
{"name": "김사과", "score": 90},
{"name": "반하나", "score": 75},
{"name": "오렌지", "score": 100}
]
def get_score(student): # 학생 한 명 한명이 들어가면 score 을 뽑는다
return student["score"]
result= sorted(students, key=get_score)
실행 결과
[{'name': '반하나', 'score': 75}, {'name': '김사과', 'score': 90}, {'name': '오렌지', 'score': 100}]
👉 여기서
key=get_score
부분을 잘 살펴보자
👉 sorted()는 학생 한 명씩 꺼내서get_score(student) 를 호출하고, 반환된 값을 기준으로 정렬한다.
즉,
90 → 75 → 100 이라는 점수를 꺼내 비교해서
75 → 90 → 100
순서로 정렬하는 것이다.
👉 데이터 분석처럼 다뤄야 할 항목들이 많을 때 이런 방식의 정렬을 자주 사용한다.
6. 람다 함수
람다 함수(lambda function)는 파이썬에서
이름 없이 간단한 함수를 한 줄로 정의할 수 있는 익명 함수로,
주로 짧고 일회성으로 사용되는 연산을 표현할 때 활용된다.
일반 함수(def)에 비해 구조는 제한적이지만 코드가 간결해지고,
특히 sorted, map, filter 같은 함수에서 콜백 함수로 자주 사용된다.
예시 1

이걸 람다 함수로 바꾸면 다음과 같이 작성할 수 있다.

✅ 람다 함수 문법은 다음과 같다.
lambda 매개변수: 반환값
즉,
:왼쪽 → 매개변수:오른쪽 → return 될 값
이라고 생각하면 된다.
예시 2 – 조건문이 들어간 람다 함수
람다 함수 안에서도 간단한 조건문을 사용할 수 있다.

👉 이 람다 함수에는 조건부 표현식이 이용되었다
조건부 표현식은
"참일 때 값" if 조건 else "거짓일 때 값"
구조이다.
즉,
score >= 60
이면 "합격"을 반환하고,
그렇지 않으면 "불합격"을 반환하는 구조이다.
예시 3 – sorted()와 람다함수
람다 함수는 정렬할 때 정말 자주 등장한다.
예를 들어 학생 정보를 점수 기준으로 내림차순 정렬한다고 해보자.
students = [
{"name": "김사과", "score": 90},
{"name": "반하나", "score": 75},
{"name": "오렌지", "score": 100},
]
# result= sorted(students, key=get_score)
result= sorted(students,key=lambda student : student["score"], reverse=True)
print(result)
👉 여기서 아래 부분이 처음에 헷갈렸다.
key=lambda student : student["score"]
파이썬은 students 안의 데이터를 하나씩 꺼내면서
student["score"]
를 실행한다.
즉,
90 → 75 → 100
이라는 점수를 꺼내고,
그 값을 기준으로 학생 정보를 정렬하는 것이다.
👉 reverse=True는 내림차순 정렬을 의미하기 때문에 students는 큰 점수를 받은 학생 순으로 정렬된다.
예시 4 – map()과 람다 함수
map() 함수는 리스트의 각 요소에 같은 작업을 반복 적용할 때 사용한다.
문법은 다음과 같다.
map(함수, 반복가능한 객체)
즉, 리스트 전체에 같은 함수를 반복 적용한다고 생각하면 이해하기 쉽다.
예를 들어 모든 점수에 10점을 더한다고 해보자.

여기서
lambda score: score + 10
은 점수를 하나씩 받아서 10을 더하는 함수이다.
👉 list()를 씌운 이유는 map()이 결과를 바로 리스트로 반환하지 않기 때문이다.
map 객체 형태로 반환되기 때문에, 실제 값을 보기 위해 list()로 변환해주었다.
예시 5 – filter()와 람다 함수
filter()는 조건에 맞는 데이터만 걸러낼 때 사용한다.
문법은 다음과 같다.
filter(함수, 반복가능한 객체)
예를 들어 60점 이상인 점수만 남긴다고 해보자.

👉 파이썬은 리스트를 하나씩 확인하면서
score >= 60
조건을 검사한다.
조건이 True인 값만 남기기 때문에,
70, 88, 100
만 결과로 남는다.
👉 filter() 역시 filter 객체를 반환하기 때문에 실제 값을 확인하려면 list()로 감싸서 사용한다.
'python' 카테고리의 다른 글
| 11. 객체 지향 프로그래밍 4대 패러다임 ① (0) | 2026.05.28 |
|---|---|
| 10. 객체지향 프로그래밍 (0) | 2026.05.28 |
| 9. 사용자 정의 함수 ① (0) | 2026.05.27 |
| Python - 제어문-반복문 (0) | 2026.05.27 |
| Python - 컬렉션 - 튜플(tuple) (0) | 2026.05.26 |