함수(Function)
함수란 주어진 입력에 대해서 정해진 동작을 하고 필요시 결과값을 반환하는 코드 묶음이다. 이를 사용하는 이유는 크게 두 가지다.
1. 반복적으로 사용되는 기능을 재사용하기 위해서다.
2. 한 번만 쓰이는 코드라도 기능별로 묶기 위해서다.
위 두 이유에 따라 전체 코드를 간결히 할 수 있고 기능 단위로 묶음으로 코드를 계층적으로 구조화해서 가독성을 높이며 특정 기능을 하는 코드를 찾아 수정하는 일도 편해진다.
- 함수 정의
파이썬에서는 C언어 처럼 함수 선언 함수 정의를 나누지 않고 바로 정의만하면 된다. 다중 입력과 다중 출력을 지원하고 입력이나 출력이 없을 수 있다. 기본적인 구조는 다음과 같다.
def function_name(arg1, arg2):
statement1
statement2
return out1, out2
def function_no_output(arg1, arg2):
statement1
statement2
def function_no_input_output():
statement1
statement2
다음과 같이 리스트 평균을 내는 함수가 있다 하자. 이 함수는 리스트(data)의 평균을 구하는 함수인데 시작 인덱스(start)와 끝 인덱스(end)를 지정할 수 있고 계산에 빠져야할 값(skip)과 계산 결과를 프린트할지 여부(verbose)를 지정할 수 있다.
def average_list(data, start, end, skip, verbose):
if end:
data = data[:end]
if start:
data = data[start:]
if skip:
for val in skip:
if val in data:
data.remove(val)
sumval = 0
for d in data:
sumval += d
average = sumval / len(data)
if verbose:
print(f"average over indices [{start}~{end}) with skipping values {skip} = {average}")
return average
- Keyword Arguments
파이썬은 동적 타입이기 때문에 어떤 값을 넣어도 일단 실행된다. 그렇기 때문에 함수에 입력인자가 많을 때 순서에 맞지 않는 입력 인자를 넣는 문제가 생길 가능성이 크다. 위에서 정의한 함수는 메인문에서 다음과 같이 사용할 수 있다.
data = [1, 2, 3, 4, 5, 6, 7, 8, 9]
avg = average_list(data, 2, 7, [4], True)
이렇게 입력인자가 많을 경우 어느 인자를 몇 번째에 넣어야 하는지 헷갈릴 수 있다. 혹은 다른 사람이 보면 무슨 데이터를 넣는지 의미를 이해하기 어렵다.
파이썬은 명시적인 코드를 선호하기에 다음과 같이 Keyword Argument(키워드 인자)를 사용한다. 반면 기존 방식대로 순서에 의해 할당되는 입력 인자를 Positional Argument(위치 인자)라 한다.
avg = average_list(data, 2, 7, skip=[4], verbose=True)
avg = average_list(data, 2, end=7, skip=[4], verbose=True)
avg = average_list(data, start=2, end=7, skip=[4], verbose=True)
avg = average_list(data=data, start=2, end=7, skip=[4], verbose=True)
이때 유의할 점으로 위치 인자와 섞어 쓸 경우 키워드 인자는 반드시 위치 인자 뒤에 와야 한다.
그렇기에 아래와 같은 코드는 에러가 발생한다.
avg = average_list(data, start=2, 7, [4])
더 들어가 생각해보면 키워드 인자는 어느 값이 들어가는지 지정해준다. 그렇기에 키워드 인자끼리는 순서를 섞어 사용해도 된다. 이때도 위치 인자는 먼저 쓰고 키워드 인자를 써야한다.
avg = average_list(data, start=2, end=7, skip=[4], verbose=True)
avg = average_list(data, end=7, start=2, skip=[4], verbose=True)
avg = average_list(data, skip=[4], start=2, end=7, verbose=True)
- 인자 기본값 지정
위 함수는 다섯 개의 입력 인자로 리스트의 평균 계산 과정을 자세히 조절할 수 있지만 메인 기능은 단순히 리스트 전체 평균을 구하는 것이다. 이때 함수에 data외에 불필요한 나머지 입력인자를 다 써주는 것이 번거로울 수 있다. data로 들어오는 필수 인자를 제외하고 나머지 인자에 기본 값을 지정해주면 번거로움을 해결 할 수 있따.
C언어와 동일하게 함수(argument = default_value)로 할해주면 된다. 위 함수에 추가로 함수를 만들겠다.
def average_list_with_default(data, start=None, end=None, skip=None, verbose=False):
return average_list(data, start, end, skip, verbose)
avg = average_list_with_default(data)
print("1. average_list_with_default(data) =>", avg)
avg = average_list_with_default(data, 3)
print("2. average_list_with_default(data, 3) =>", avg)
avg = average_list_with_default(data, end=5)
print("3. average_list_with_default(data, end=5) =>", avg)
위 함수에 대해 간단히 설명해보면 다음과 같다.
1. data를 제외한 나머지 인자를 기본값으로 사용
2. start까지 값 입력
3. 키워드 인자를 사용하여 start는 기본값을, end만 입력을 사용
- 변수 범위(Scope)
변수 범위란 코드에서 변수에 접근 가능한 범위를 말한다. C언어 에서는 {}로 묶인 범위 안에서 선언된 변수는 {}안에서만 사용 가능하다. 파이썬은 들여쓰기로 코드 블럭을 구분하지만 블록 안에서 선언한 변수는 밖에서도 사용 가능하다. 하지만 이 경우 블록이 실행되어야만 해당 변수를 에러 없이 사용 가능하다.
if True:
var_created = "created"
print("variable created inside block:", var_created)
if False:
var_not_created = "not created"
try:
print("variable NOT created inside block:", var_not_created)
except NameError as ne:
print(ne)
출력 :
variable created inside block: created
name 'var_not_created' is not defined
하지만 함수 내부에 선언한 변수는 지역 변수로 인식되어 외부에서 사용 불가하다. 반대로 함수 외부에서 선언된 변수는 전역 변수로 인식되어 내부에서 사용 가능하다. 함수 내부 어느 위치에서든 myvariable = value와 같이 변수에 값을 넣는 코드가 있으면 해당 변수는 모두 지역 변수로 인식한다. 이때 myvariable을 지역 변수로 인식하는 함수가 있고 그 외부에도 myvariable이라는 전역 변수가 있을 때 지역 변수를 생성하기 전에 전역 변수로 값을 읽어들이면 에러가 난다. 함수 내부에서 전역 변수의 값을 바꾸고 싶다면 내부에서 globa var_name을 선언해줘야 한다.
global_var = 10
def add_ten_local(): # 값 가져다 쓰기 가능
local_var = global_var + 10
print("add_ten_local:", local_var)
def add_ten_global(): # 에러 발생
try:
global_var = global_var + 10
print("add_ten_global:", global_var)
except NameError as ne:
print(ne)
def add_ten_global_two_steps(): # 에러 발생
try:
local_var = global_var + 10
global_var = local_var
print("add_ten_global_two_steps:", global_var)
except NameError as ne:
print(ne)
def add_ten_global_use_global(): # 내부에 global 선언
global global_var
global_var = global_var + 10
print("add_ten_global_use_global:", global_var)
add_ten_local()
add_ten_global()
add_ten_global_two_steps()
add_ten_global_use_global()
print("global_var=", global_var)
출력 :
add_ten_local: 20
cannot access local variable 'global_var' where it is not associated with a value
cannot access local variable 'global_var' where it is not associated with a value
add_ten_global_use_global: 20
global_var= 20
- 바람직한 파이썬 코딩
지금 예제들을 다룬 것처럼 함수 밖에 코드를 쓰지 않는다. 왜냐하면 변수들이 모두 전역 변수로 인식되어 함수 내부 변수들과 섞여 버그가 발생할 가능성이 높기 때문이다. 따라서 모든 코드를 함수 안에 작성해준다. 실행 될 메인 함수를 먼저 만들고 함수 밖에는 메인 함수를 호출하는 코드만 넣어준다. 후에 메인 함수 안에 기능 별로 묶은 세부 함수로 나누어 세부 함수들을 호출한다.
실습한 코드들을 위에 맞추어 작성해보겠다.
def main():
data = [1, 2, 3, 4, 5, 6, 7, 8, 9]
result = average_list_with_default(data, 10, start=1, skip=[2, 3])
print("average_keyworded_args(data, start=1, skip=[2, 3]) =>", result)
result = average_list_with_default(data, 10, start=1, end=7)
print("average_keyworded_args(data, start=1, end=7) =>", result)
def average_list_with_default(data, start=0, end=None, skip=None, verbose=False):
return average_list(data, start, end, skip, verbose)
def average_list(data, start, end, skip, verbose):
if end:
data = data[:end]
if start:
data = data[start:]
if skip:
for val in skip:
if val in data:
data.remove(val)
sumval = 0
for d in data:
sumval += d
average = sumval / len(data)
if verbose:
print(f"average over indices [{start}~{end}) with skipping values {skip} = {average}")
return average
if __name__ == '__main__':
main()
맨 아래에 if __name__ == '__main__':이라는 조건문이 보인다. 이는 스크립트 파일이 직접 실행된 것인지 확인하는 것이다. 여러 파일이 연계되서 실행될 때 이 스크립트가 주로 실행되는 스크립트인지 다른 스크립트에서 사용되는 것인지 확인하는 것이다. 주로 실행되는 스크립트인지 확인하고 main() 함수를 실행한다. 호출하는 함수는 호출 받는 함수 위에 선언하여 자연스럽게 읽을 수 있는 코드로 작성하자.
'학부 생활 + 랩실 > Python' 카테고리의 다른 글
| 파이썬(8) - 클래스 (0) | 2026.04.04 |
|---|---|
| 파이썬(7) - 패키지 (0) | 2026.04.04 |
| 파이썬(5) - 제어문 (0) | 2026.04.03 |
| 파이썬(4) - 컨테이너(2) 딕셔너리, 튜플 (0) | 2026.04.03 |
| 파이썬(3) - 컨테이너(1) 리스트 (1) | 2026.04.03 |