소개
이 랩에서는 Python 함수를 정의하고 사용하는 방법을 배우게 됩니다. 간단한 예시부터 시작하여 점차적으로 복잡성을 높여갈 것입니다.
시작해 봅시다!
성과
- Python 함수
Python 함수 정의하기
Python 함수를 정의하려면 def 키워드를 사용하고, 그 뒤에 함수 이름과 인수를 포함할 수 있는 괄호를 붙입니다. 함수 본문은 들여쓰기 되어 있으며 : 문자를 따릅니다.
새로운 Python 인터프리터를 엽니다.
python3
다음은 단일 인수 x를 받아 x의 제곱을 반환하는 간단한 함수의 예시입니다.
def square(x):
return x ** 2
이 예시에서 square 함수는 단일 인수 x를 받아 x의 제곱을 반환합니다. 값은 return 문을 사용하여 호출자에게 반환됩니다.
함수를 호출하려면 함수 이름 뒤에 괄호와 필요한 인수를 붙이면 됩니다. 예를 들어:
result = square(5) ## result is 25
print(result)
함수에 return 문이 없으면 기본적으로 None을 반환합니다. 예를 들어:
def square(x):
print(x ** 2)
result = square(5) ## result is None
print(result)
return 문과 print 문의 차이점을 알아야 합니다. print 문은 화면에 값을 출력하는 데 사용되지만, return 문은 함수에서 값을 반환하는 데 사용됩니다.
또한 return 문을 사용하여 함수의 실행을 조기에 종료할 수도 있습니다. 예를 들어:
def find_first_positive(numbers):
for number in numbers:
if number > 0:
return number
return None
result = find_first_positive([-1, -2, 3, -4, 5]) ## result is 3
print(result)
이 예시에서 find_first_positive 함수는 numbers 리스트에서 첫 번째 양수를 반환하거나, 양수가 없으면 None을 반환합니다. return 문은 양수가 발견되는 즉시 함수의 실행을 종료합니다.
함수 인자
때로는 함수 인수에 기본값을 지정하는 것이 유용합니다. 이렇게 하면 해당 인수에 대한 값을 전달하지 않고 함수를 호출할 수 있으며, 대신 기본값이 사용됩니다.
다음은 직사각형의 면적을 계산하는 함수의 예시입니다. 두 개의 인수, 즉 직사각형의 길이와 너비를 받습니다. 두 인수 모두에 기본값을 지정할 수 있으므로, 길이와 너비가 같으면 함수를 하나의 인수만으로 호출할 수 있습니다.
def rectangle_area(length, width=1):
return length * width
print(rectangle_area(5)) ## Output: 5
print(rectangle_area(5, 2)) ## Output: 10
이 예시에서 width 인수는 기본값 1 을 갖습니다. 함수가 하나의 인수만으로 호출되면 width에 대해 기본값 1 이 사용됩니다.
직접 해보세요: 밑수 x와 지수 n의 두 인수를 받는 power라는 함수를 정의합니다. 지수 인수를 선택적으로 만들고 기본값을 2 로 설정합니다. 그런 다음 밑수와 지수에 대해 다른 값으로 함수를 호출합니다.
def power(x, n=2):
return x ** n
print(power(2)) ## Output: 4
print(power(2, 3)) ## Output: 8
인수 타입 힌트 (Argument Type Hint)
Python 에서 함수 인수 타입 힌트는 함수에 전달된 인수의 예상 타입을 나타냅니다. Python 3.5 에서 도입되었으며, 함수 정의에서 인수 이름 뒤에 콜론과 타입이 함께 표시됩니다.
타입 힌트는 선택 사항이며 코드의 런타임 동작에 영향을 미치지 않습니다. 주로 IDE 및 린터와 같은 도구에서 더 나은 코드 분석 및 자동 완성 제안을 제공하는 데 사용됩니다.
예를 들어, 정수와 문자열의 두 인수를 받아 연결을 반환하는 다음 함수를 고려하십시오.
def concatenate(a: int, b: str) -> str:
return str(a) + b
print(concatenate(1, "world")) ## "1world"
이 예시에서 타입 힌트 int와 str은 첫 번째 인수 a가 정수여야 하고 두 번째 인수 b가 문자열이어야 함을 나타냅니다.
타입 힌트는 클래스 및 해당 인스턴스와 함께 사용할 수도 있습니다. 예를 들어:
class MyClass:
pass
def my_function(a: MyClass) -> None:
pass
타입 힌트는 선택 사항이며 코드의 런타임 동작에 영향을 미치지 않는다는 점을 언급할 가치가 있습니다. 주로 IDE 및 린터와 같은 도구에서 더 나은 코드 분석 및 자동 완성 제안을 제공하는 데 사용됩니다.
또한 Python 에는 typing이라는 모듈이 있으며, List, Tuple, Dict, Set 등과 같은 유용한 타입이 포함되어 있어 컬렉션의 요소 타입에 대한 힌트를 제공하는 데 사용할 수 있습니다.
from typing import List, Tuple
def my_function(a: List[int], b: Tuple[str, int]) -> None:
pass
코드를 더 읽기 쉽고 유지 관리 가능하게 만들려면 타입 힌트를 사용하는 것이 좋습니다.
Docstring
Docstring 은 모듈, 함수, 클래스 또는 메서드 정의의 첫 번째 문으로 나타나는 문자열 리터럴입니다. 이러한 docstring 은 해당 객체의 __doc__ 특수 속성이 됩니다.
Docstring 은 코드를 문서화하는 데 사용되며 일반 텍스트로 작성됩니다. 삼중 따옴표 """로 묶여 있으며 일반적으로 함수 정의의 시작 부분에 배치됩니다.
def my_function():
"""This is a docstring."""
pass
Docstring 은 일반적으로 함수의 짧은 설명, 해당 인수 및 반환 값을 포함합니다. 또한 함수의 동작에 대한 더 긴 설명을 포함할 수도 있습니다.
def my_function(a: int, b: int) -> int:
"""Return the sum of a and b.
Args:
a (int): The first number.
b (int): The second number.
Returns:
int: The sum of a and b.
"""
return a + b
여러 값 반환
Python 에서 함수는 튜플을 사용하여 여러 값을 반환할 수 있습니다. 다음은 리스트의 최소값과 최대값을 계산하는 함수의 예시입니다.
def min_max(numbers):
return min(numbers), max(numbers)
nums = [1, 2, 3, 4, 5]
min_val, max_val = min_max(nums)
print("Minimum value:", min_val) ## Output: "Minimum value: 1"
print("Maximum value:", max_val) ## Output: "Maximum value: 5"
이 예시에서 min_max 함수는 numbers 리스트의 최소값과 최대값을 포함하는 튜플을 반환합니다. 함수가 호출될 때 튜플은 min_val 및 max_val 변수로 언패킹됩니다.
다음은 함수에서 여러 값을 반환하는 또 다른 예시입니다.
def get_student_info(name):
if name == "John":
return "John", "Doe", "Computer Science"
elif name == "Jane":
return "Jane", "Smith", "Physics"
else:
return "Unknown", "Unknown", "Unknown"
first_name, last_name, major = get_student_info("John")
print("First name:", first_name) ## Output: "First name: John"
print("Last name:", last_name) ## Output: "Last name: Doe"
print("Major:", major) ## Output: "Major: Computer Science"
first_name, last_name, major = get_student_info("Jane")
print("First name:", first_name) ## Output: "First name: Jane"
print("Last name:", last_name) ## Output: "Last name: Smith"
print("Major:", major) ## Output: "Major: Physics"
first_name, last_name, major = get_student_info("Bob")
print("First name:", first_name) ## Output: "First name: Unknown"
print("Last name:", last_name) ## Output: "Last name: Unknown"
print("Major:", major) ## Output: "Major: Unknown"
이 예시에서 get_student_info 함수는 학생 이름을 받아 학생의 이름, 성, 전공을 포함하는 튜플을 반환합니다. 함수가 호출될 때 튜플은 별도의 변수로 언패킹됩니다.
학생 이름을 인식할 수 없는 경우 함수는 "Unknown" 값을 가진 튜플을 반환합니다.
키워드 인자
Python 에서는 "키워드 인수"를 사용하여 함수 인수를 지정할 수 있습니다. 키워드 인수를 사용할 때는 인수 이름 뒤에 값을 지정하며, 인수는 어떤 순서로든 제공될 수 있습니다.
다음은 이름과 메시지, 두 개의 인수를 받는 함수의 예시입니다.
def greet(name, message):
print("Hello, " + name + "! " + message)
greet(message="How are you?", name="John") ## Output: "Hello, John! How are you?"
이 예시에서 greet 함수는 "John"과 "How are you?" 인수로 호출되지만, 인수는 함수에 정의된 순서와 다른 순서로 제공됩니다. 키워드 인수를 사용하면 인수를 어떤 순서로든 지정할 수 있으며 코드를 더 읽기 쉽게 만들 수 있습니다.
위치 인수와 키워드 인수를 혼합하여 사용할 수도 있습니다. 단, 위치 인수가 먼저 제공되어야 합니다. 예를 들어:
def greet(name, message):
print("Hello, " + name + "! " + message)
greet("John", message="How are you?") ## Output: "Hello, John! How are you?"
이 예시에서 name 인수는 위치 인수로 제공되고, message 인수는 키워드 인수로 제공됩니다.
키워드 인수는 함수에 많은 수의 인수가 있거나 인수에 기본값이 있는 경우 특히 유용합니다. 예를 들어:
def create_user(name, age=18, gender="unknown"):
print("Creating user:", name, age, gender)
create_user("John") ## Output: "Creating user: John 18 unknown"
create_user("Jane", gender="female") ## Output: "Creating user: Jane 18 female"
create_user("Bob", 25, "male") ## Output: "Creating user: Bob 25 male"
이 예시에서 create_user 함수는 name, age, gender 세 개의 인수를 받습니다. age 및 gender 인수는 기본값을 가지므로 선택 사항입니다. 키워드 인수를 사용하면 제공하려는 인수만 지정할 수 있으며, 나머지 인수에 대해서는 기본값이 사용됩니다.
Args 와 Kwargs (가변 인자)
Python 에서는 *args 및 **kwargs 구문을 사용하여 가변 개수의 인수를 받을 수 있는 함수를 정의할 수 있습니다.
*args 구문은 가변 개수의 키워드 없는 인수를 함수에 전달하는 데 사용됩니다. 예를 들어:
def print_numbers(*args):
for arg in args:
print(arg)
print_numbers(1, 2, 3, 4, 5) ## Output: 1, 2, 3, 4, 5
print_numbers(10, 20, 30) ## Output: 10, 20, 30
이 예시에서 print_numbers 함수는 가변 개수의 인수를 받아 콘솔에 출력합니다. *args 구문은 함수를 정의하는 데 사용되며, 인수는 튜플로 함수에 전달됩니다.
**kwargs 구문은 가변 개수의 키워드 인수를 함수에 전달하는 데 사용됩니다. 예를 들어:
def print_keywords(**kwargs):
for key, value in kwargs.items():
print(key, ":", value)
print_keywords(name="John", age=30, city="New York")
## Output:
## name : John
## age : 30
## city : New York
print_keywords(country="USA", population=327000000)
## Output:
## country : USA
## population : 327000000
이 예시에서 print_keywords 함수는 가변 개수의 키워드 인수를 받아 콘솔에 출력합니다. **kwargs 구문은 함수를 정의하는 데 사용되며, 인수는 딕셔너리로 함수에 전달됩니다.
*args 및 **kwargs 구문은 함수 정의에서 다른 인수와 혼합하여 사용할 수 있으며, *args 및 **kwargs 인수가 마지막에 제공되어야 합니다. 예를 들어:
def print_info(title, *args, **kwargs):
print(title)
for arg in args:
print(arg)
for key, value in kwargs.items():
print(key, ":", value)
print_info("Person", "John", "Jane", "Bob", age=30, city="New York")
## Output:
## Person
## John
## Jane
## Bob
## age : 30
## city : New York
이 예시에서 print_info 함수는 고정 인수 title, 그 다음 가변 개수의 키워드 없는 인수 (*args), 마지막으로 가변 개수의 키워드 인수 (**kwargs) 를 받습니다. 인수는 정의된 순서대로 함수에 전달됩니다: 먼저 title, 그 다음 *args, 마지막으로 **kwargs.
*args 및 **kwargs 구문은 가변 개수의 인수를 허용하는 유연한 함수를 정의하려는 경우 유용합니다. 또한 함수 정의에서 하드 코딩된 인수 이름을 사용하지 않도록 하여 코드를 더 읽기 쉽게 만들 수 있습니다.
다음은 *args 및 **kwargs를 사용하여 인수의 딕셔너리를 만드는 함수의 예시입니다.
def create_dict(**kwargs):
return kwargs
my_dict = create_dict(name="John", age=30, city="New York")
print(my_dict) ## Output: {'name': 'John', 'age': 30, 'city': 'New York'}
my_dict = create_dict(a=1, b=2, c=3)
print(my_dict) ## Output: {'a': 1, 'b': 2, 'c': 3}
이 예시에서 create_dict 함수는 가변 개수의 키워드 인수를 받아 딕셔너리로 반환합니다. **kwargs 구문은 함수를 정의하는 데 사용되며, 인수는 딕셔너리로 함수에 전달됩니다.
함수를 호출할 때 * 연산자를 사용하여 리스트 또는 튜플을 개별 인수로 "언패킹"할 수도 있습니다. 예를 들어:
def print_numbers(*args):
for arg in args:
print(arg)
numbers = [1, 2, 3, 4, 5]
print_numbers(*numbers) ## Output: 1, 2, 3, 4, 5
tuple_of_numbers = (10, 20, 30)
print_numbers(*tuple_of_numbers) ## Output: 10, 20, 30
이 예시에서 * 연산자는 numbers 리스트와 tuple_of_numbers 튜플을 print_numbers 함수를 호출할 때 개별 인수로 언패킹하는 데 사용됩니다.
함수를 호출할 때 ** 연산자를 사용하여 딕셔너리를 키워드 인수로 "언패킹"할 수도 있습니다. 예를 들어:
def print_keywords(**kwargs):
for key, value in kwargs.items():
print(key, ":", value)
my_dict = {'name': 'John', 'age': 30, 'city': 'New York'}
print_keywords(**my_dict)
## Output:
## name : John
## age : 30
## city : New York
another_dict = {'country': 'USA', 'population': 327000000}
print_keywords(**another_dict)
## Output:
## country : USA
## population : 327000000
이 예시에서 ** 연산자는 my_dict 및 another_dict 딕셔너리를 print_keywords 함수를 호출할 때 키워드 인수로 언패킹하는 데 사용됩니다.
람다 함수 (Lambda Functions)
Python 에서는 "람다 함수"를 사용하여 익명 함수를 만들 수 있습니다. 람다 함수는 이름이 없는 작은 함수이며, 일반적으로 한 줄의 코드에서 정의되고 호출됩니다.
다음은 두 개의 인수를 받아 그 합을 반환하는 람다 함수의 예시입니다.
sum = lambda x, y: x + y
result = sum(1, 2) ## result is 3
이 예시에서 lambda 키워드는 두 개의 인수 x와 y를 받아 그 sum을 반환하는 람다 함수를 정의하는 데 사용됩니다. 람다 함수는 sum 변수에 할당되며, 다른 함수와 마찬가지로 호출할 수 있습니다.
동일한 함수를 정의하기 위해 람다 함수 대신 일반 함수를 사용할 수 있습니까?
def sum(x, y):
return x + y
result = sum(1, 2) ## result is 3
람다 함수는 간단한 함수를 정의하기 위한 바로가기로 자주 사용됩니다. 특히 함수를 다른 함수의 인수로 전달하거나, 함수를 인라인으로 정의하려는 경우 유용합니다.
다음은 sorted 함수에 대한 인수로 람다 함수를 사용하는 예시입니다.
words = ["apple", "banana", "cherry", "date"]
sorted_words = sorted(words, key=lambda x: len(x))
print(sorted_words) ## Output: ['apple', 'date', 'banana', 'cherry']
이 예시에서 sorted 함수는 단어 목록과 단어 정렬 방식을 지정하는 "key" 함수를 받습니다. key 함수로 전달된 람다 함수는 각 단어의 길이를 반환하며, 단어는 길이를 기준으로 정렬됩니다.
다음은 람다 함수를 인라인으로 정의하는 예시입니다.
result = (lambda x: x ** 2)(5) ## result is 25
이 예시에서 람다 함수는 단일 인수 x를 받아 x의 제곱을 반환합니다. 람다 함수는 한 줄의 코드에서 정의되고 호출되며, result는 결과 변수에 할당됩니다.
람다 함수는 코드의 다른 곳에서 재사용할 필요가 없는 짧고 간단한 함수에 대해 Python 에서 자주 사용됩니다. def 키워드를 사용하여 별도의 함수를 정의할 필요 없이 작은 함수를 즉석에서 정의하는 편리한 방법입니다.
지역 및 전역 범위 (Local and Global Scope)
Python 에서 함수 내부에 정의된 변수는 함수에 "지역적 (local)"이며, 함수 내부에서만 사용할 수 있습니다. 함수 외부에서 정의된 변수는 "전역적 (global)"이며 전체 프로그램에서 사용할 수 있습니다.
다음은 전역 변수의 예시입니다.
message = "Hello, world!"
def greet():
print(message)
greet() ## Output: "Hello, world!"
이 예시에서 message 변수는 greet 함수 외부에서 정의되었으므로 global 변수입니다. greet 함수는 전체 프로그램에서 사용할 수 있으므로 message 변수에 접근하여 출력할 수 있습니다.
다음은 지역 변수의 예시입니다.
def greet(name):
message = "Hello, " + name + "!"
print(message)
greet("John") ## Output: "Hello, John!"
print(message) ## Output: NameError: name 'message' is not defined
이 예시에서 message 변수는 greet 함수 내부에서 정의되었으므로 지역 변수입니다. greet 함수는 message 변수에 접근하여 출력할 수 있지만, 함수 외부에서는 사용할 수 없습니다. 함수 외부에서 message 변수에 접근하려고 하면 변수가 정의되지 않았기 때문에 NameError가 발생합니다.
global 키워드를 사용하여 함수 내부에서 전역 변수를 수정할 수도 있습니다. 예를 들어:
message = "Hello, world!"
def greet():
global message
message = "Hello, Python!"
print(message)
greet() ## Output: "Hello, Python!"
print(message) ## Output: "Hello, Python!"
이 예시에서 greet 함수는 global 키워드를 사용하여 message 전역 변수를 수정합니다. greet 함수는 수정된 message 값을 출력하고, message의 값은 함수 외부에서도 수정됩니다.
일반적으로 global 변수를 사용하는 것을 피하는 것이 좋습니다. 왜냐하면 코드를 이해하고 유지 관리하기 더 어렵게 만들 수 있기 때문입니다. global 변수를 수정하는 것보다 변수를 함수에 인수로 전달하고 결과를 반환하는 것이 더 좋습니다.
함수를 다른 함수의 인자로 사용하기
Python 에서는 함수를 다른 함수의 인수로 전달할 수 있습니다. 이를 "고차 함수 (higher-order function)"라고 합니다. 다음은 다른 함수를 인수로 받아 여러 번 호출하는 함수의 예시입니다.
def greet(name):
print("Hello, " + name + "!")
def call(func, args):
for arg in args:
func(arg)
names = ["John", "Jane", "Bob"]
call(greet, names) ## Output: "Hello, John!", "Hello, Jane!", "Hello, Bob!"
이 예시에서 call 함수는 두 개의 인수를 받습니다: 함수 func와 인수 목록 args. args 목록의 각 요소에 대해 func 함수를 호출합니다.
직접 해보세요: 함수와 숫자 목록을 인수로 받아 목록의 각 요소에 함수를 적용한 결과를 포함하는 새 목록을 반환하는 apply라는 함수를 정의하십시오.
def square(x):
return x ** 2
def apply(func, numbers):
result = []
for number in numbers:
result.append(func(number))
return result
numbers = [1, 2, 3, 4, 5]
squared_numbers = apply(square, numbers)
print(squared_numbers) ## Output: [1, 4, 9, 16, 25]
이 단계는 약간 어려울 수 있습니다. 해결하지 못하더라도 걱정하지 마세요. 건너뛰고 나중에 다시 시도할 수 있습니다.
요약
이제 Python 함수를 사용하는 방법에 대한 훌륭한 이해를 갖게 되셨을 것입니다. 다음은 몇 가지 주요 사항입니다.
- Python 함수는 정의, 호출 및 재사용할 수 있는 코드 블록입니다.
def키워드, 함수 이름 및 인수를 사용하여 함수를 정의할 수 있습니다.- 함수 본문은 들여쓰기해야 하며,
return키워드를 사용하여 함수에서 값을 반환할 수 있습니다. - "키워드 인수 (keyword arguments)"를 사용하여 함수 인수를 지정할 수 있으며, 이를 통해 함수를 호출할 때 인수 이름과 값을 지정할 수 있습니다.
*args구문을 사용하여 가변 개수의 비 키워드 인수를 사용할 수 있는 함수를 정의하고,**kwargs구문을 사용하여 가변 개수의 키워드 인수를 사용할 수 있는 함수를 정의할 수 있습니다.lambda키워드를 사용하여 한 줄의 코드에서 정의되고 호출되는 익명 함수 (anonymous functions) 를 만들 수 있습니다.- Python 에서 함수 내부에 정의된 변수는 함수에 지역적 (local) 이며 함수 내부에서만 사용할 수 있습니다. 함수 외부에서 정의된 변수는 전역적 (global) 이며 전체 프로그램에서 사용할 수 있습니다.
- 일반적으로 전역 변수를 사용하지 않고, 대신 변수를 함수에 인수로 전달하고 결과를 반환하는 것이 좋습니다.



