2. 함수 고급 활용
함수 고급 활용에서는 재귀 함수, 가변 인자와 키워드 인자, 데코레이터, 제너레이터와 같은 고급 함수 사용법을 다룹니다. 이를 통해 코드의 재사용성과 유지 보수성을 높이고, 효율적인 프로그래밍 기법을 익히게 됩니다.
2.1 클로저와 데코레이터
2.1.1 클로저 개념과 활용 방법
- 클로저는 함수 내부에서 정의된 내부 함수(inner function)로, 외부 함수의 변수를 참조하고 저장할 수 있는 기능을 가진 함수입니다.
- 클로저는 외부 함수가 종료된 이후에도 내부 함수가 외부 함수의 변수를 참조할 수 있게 해 줍니다.
예제 코드
def outer_function(x):
def inner_function(y):
return x + y
return inner_function
closure = outer_function(10)
print(closure(5)) # Output: 15
2.1.2 클로저의 특징과 클로저의 활용 예시
- 클로저는 상태를 저장하고 유지할 수 있으며, 모듈화와 캡슐화에 도움을 줍니다.
- 클로저의 활용 예시로는 카운터, 지연된 실행(lazy evaluation), 콜백 함수 등이 있습니다.
2.1.3 데코레이터 개념과 활용 방법
- 데코레이터는 기존의 함수나 클래스에 새로운 기능을 추가하는 데 사용되는 도구입니다. 데코레이터는 기존 코드를 수정하지 않고 기능을 확장할 수 있게 해 줍니다.
예제 코드
def decorator_function(func):
def wrapper(*args, **kwargs):
print("Function is being called")
return func(*args, **kwargs)
return wrapper
@decorator_function
def my_function():
print("Hello, World!")
my_function()
2.1.4 데코레이터의 특징과 데코레이터의 활용 예시
- 데코레이터는 유연하게 코드를 확장할 수 있으며, 코드 중복을 줄여줍니다.
- 데코레이터의 활용 예시로는 로깅(logging), 타이머(timer), 권한 검사(permission check) 등이 있습니다.
2.1.5 데코레이터의 종류
2.1.5.1 클래스 데코레이터
- 클래스를 받아 새로운 클래스를 반환하는 데코레이터입니다.
예제 코드
class Component:
pass
def class_decorator(cls):
class Wrapper(cls):
def decorated_method(self):
print("Decorated method called")
super().method()
return Wrapper
@Component
class MyClass(Component):
def method(self):
print("Original method called")
my_object = MyClass()
my_object.decorated_method()
2.1.5.2 함수 데코레이터
- 함수를 받아 새로운 함수를 반환하는 데코레이터입니다.
예제 코드
def decorator_function(func):
def wrapper(*args, **kwargs):
print("Function is being called")
return func(*args, **kwargs)
return wrapper
@decorator_function
def my_function():
print("Hello, World!")
my_function()
2.1.5.3 매개변수화된 데코레이터
- 매개변수를 받아 데코레이터를 반환하는 데코레이터입니다.
예제 코드
def decorator_with_arguments(arg1, arg2):
def decorator_function(func):
def wrapper(*args, **kwargs):
print(f"Arguments passed: {arg1}, {arg2}")
return func(*args, **kwargs)
return wrapper
return decorator_function
@decorator_with_arguments("arg1", "arg2")
def my_function():
print("Hello, World!")
my_function()
2.1.6 데코레이터 체인과 데코레이터 함수 인자 활용
- 여러 개의 데코레이터를 순차적으로 적용할 수 있습니다.
- 데코레이터를 이용해 함수 인자를 조작할 수 있습니다.
예제 코드
def square_decorator(func):
def wrapper(*args, **kwargs):
result = func(*args, **kwargs)
return result ** 2
return wrapper
def double_decorator(func):
def wrapper(*args, **kwargs):
result = func(*args, **kwargs)
return result * 2
return wrapper
@square_decorator
@double_decorator
def my_function(x):
return x + 2
print(my_function(3)) # Output: 100
2.1.7 데코레이터의 유닛 테스트
- 데코레이터가 올바르게 작동하는지 확인하기 위해 유닛 테스트를 작성할 수 있습니다.
예제 코드
import unittest
def decorator_function(func):
def wrapper(*args, **kwargs):
print("Function is being called")
return func(*args, **kwargs)
return wrapper
@decorator_function
def add(a, b):
return a + b
class TestDecorator(unittest.TestCase):
def test_add(self):
self.assertEqual(add(1, 2), 3)
if __name__ == "__main__":
unittest.main()
2.1.8 파이썬에서 기본으로 제공하는 데코레이터
- 파이썬에서는 기본으로 제공되는 데코레이터가 있습니다. 예를 들면, @staticmethod, @classmethod, @property 등이 있습니다.
예제 코드
class MyClass:
def __init__(self, x):
self._x = x
@staticmethod
def static_method():
print("This is a static method")
@classmethod
def class_method(cls):
print("This is a class method")
@property
def x(self):
return self._x
@x.setter
def x(self, value):
self._x = value
my_object = MyClass(5)
MyClass.static_method()
MyClass.class_method()
print(my_object.x)
my_object.x = 10
print(my_object.x)
2.2 제너레이터와 이터레이터
2.2.1 이터레이터 개념과 활용 방법
- 이터레이터는 값을 차례대로 꺼낼 수 있는 객체로, __iter__() 메서드와 __next__() 메서드를 구현해야 합니다.
예제 코드
class MyIterator:
def __init__(self, data):
self.data = data
self.index = 0
def __iter__(self):
return self
def __next__(self):
if self.index >= len(self.data):
raise StopIteration
value = self.data[self.index]
self.index += 1
return value
my_iterator = MyIterator([1, 2, 3])
for value in my_iterator:
print(value)
2.2.2 이터레이터 프로토콜
- 이터레이터 프로토콜은 객체의 반복을 위해 __iter__() 메서드와 __next__() 메서드를 정의하는 것입니다.
2.2.3 제너레이터 개념과 활용 방법
- 제너레이터는 이터레이터를 생성하는 함수로, yield 키워드를 사용하여 값을 반환합니다.
예제 코드
def my_generator():
yield 1
yield 2
yield 3
for value in my_generator():
print(value)
2.2.4 제너레이터 표현식
- 제너레이터 표현식은 리스트 컴프리헨션과 유사한 방식으로 제너레이터를 생성합니다.
예제 코드
generator_expression = (x ** 2 for x in range(1, 4))
for value in generator_expression:
print(value)
2.2.5 제너레이터의 활용 예시
- 제너레이터를 사용하여 메모리 효율적인 코드를 작성할 수 있습니다.
예제 코드
def fibonacci_generator(n):
a, b = 0, 1
for _ in range(n):
yield a
a, b = b, a + b
for value in fibonacci_generator(10):
print(value)
2.2.6 yield from 구문을 이용한 제너레이터 체인 만들기
- yield from 구문을 사용하면 제너레이터를 간편하게 연결할 수 있습니다.
예제 코드
def generator1():
yield 1
yield 2
yield 3
def generator2():
yield 4
yield 5
yield 6
def chain_generators():
yield from generator1()
yield from generator2()
for value in chain_generators():
print(value)
2.3 함수형 프로그래밍
2.3.1 함수형 프로그래밍 개념과 장점
- 함수형 프로그래밍은 프로그램을 수학적 함수의 평가로 간주하는 프로그래밍 패러다임입니다. 이를 통해 코드의 간결함, 모듈성, 재사용성 등의 장점을 얻을 수 있습니다.
2.3.2 고차 함수와 람다 함수
- 고차 함수는 함수를 인자로 받거나 반환하는 함수입니다. 람다 함수는 이름 없이 정의된 익명의 함수입니다.
예제 코드
def apply_func(func, x, y):
return func(x, y)
result = apply_func(lambda x, y: x + y, 3, 5)
print(result)
2.3.3 map, filter, reduce 함수 활용
- map(), filter(), reduce()는 고차 함수로, 각각 리스트를 변환, 필터링, 축약하는 데 사용됩니다.
예제 코드
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x ** 2, numbers))
print(squared)
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
print(even_numbers)
from functools import reduce
sum_of_numbers = reduce(lambda x, y: x + y, numbers)
print(sum_of_numbers)
2.3.4 파이썬에서의 함수형 프로그래밍 라이브러리
- 파이썬에서는 함수형 프로그래밍을 위한 라이브러리를 제공합니다. 예를 들어, functools, itertools, operator 등이 있습니다.
2.3.5 함수 합성과 부분 함수 적용
- 함수 합성은 여러 함수를 하나의 함수로 결합하는 것입니다. 부분 함수 적용은 함수의 일부 인자를 고정하여 새로운 함수를 생성하는 것입니다.
예제 코드
from functools import partial
def add(x, y, z):
return x + y + z
add_five = partial(add, 5)
result = add_five(3, 2)
print(result)
2.3.6 재귀 함수와 꼬리 재귀 최적화
- 재귀 함수는 자기 자신을 호출하는 함수입니다. 꼬리 재귀는 재귀 호출이 함수의 마지막 동작으로 이루어지는 경우를 말합니다. 이 경우, 컴파일러나 인터프리터가 꼬리 재귀 최적화를 수행하여 스택 오버플로우를 방지할 수 있습니다. 하지만 파이썬은 꼬리 재귀 최적화를 지원하지 않습니다.
예제 코드
def factorial_recursive(n):
if n == 1:
return 1
else:
return n * factorial_recursive(n - 1)
print(factorial_recursive(5))
2.3.7 모나드와 모나드 활용 방법
- 모나드는 함수형 프로그래밍에서 사용되는 디자인 패턴 중 하나로, 연산의 결과를 감싸고 있는 객체입니다. 모나드는 데이터를 변환하거나 체인 형태의 연산을 수행하는 데 사용됩니다.
2.3.8 파이썬에서의 모나드 구현하기
- 파이썬에서는 모나드를 클래스로 구현할 수 있습니다. 예제로, 옵션 모나드를 구현해 보겠습니다.
예제 코드
class Option:
def __init__(self, value):
self._value = value
def map(self, func):
if self._value is None:
return self
else:
return Option(func(self._value))
def get_or_else(self, default_value):
return self._value if self._value is not None else default_value
option = Option(5).map(lambda x: x * 2)
result = option.get_or_else(0)
print(result)
2.4 파이썬의 내장 함수와 라이브러리
2.4.1 파이썬의 내장 함수
- 파이썬은 다양한 내장 함수를 제공합니다. 예를 들어, len(), max(), min(), sorted() 등이 있습니다.
2.4.2 itertools 라이브러리
- itertools 라이브러리는 효율적인 반복을 위한 여러 가지 함수를 제공합니다. 예를 들어, count(), cycle(), repeat(), chain(), zip_longest() 등이 있습니다.
2.4.3 functools 라이브러리
- functools 라이브러리는 고차 함수와 관련된 여러 유용한 함수를 제공합니다. 예를 들어, partial(), reduce(), lru_cache() 등이 있습니다.
2.4.4 operator 라이브러리
- operator 라이브러리는 파이썬의 내장 연산자에 대응하는 함수를 제공합니다. 예를 들어, add(), `mul()', 'truediv()', 'lt()', 'and_()'` 등이 있습니다.
2.4.5 예제: 함수형 프로그래밍을 활용한 피보나치수열
- 이 예제에서는 함수형 프로그래밍의 개념을 활용하여 피보나치수열을 구현해 보겠습니다.
예제 코드
from functools import lru_cache
@lru_cache(maxsize=None)
def fibonacci(n):
if n == 0:
return 0
elif n == 1:
return 1
else:
return fibonacci(n - 1) + fibonacci(n - 2)
print([fibonacci(i) for i in range(10)])
파이썬에서의 함수, 데코레이터, 이터레이터, 제너레이터, 함수형 프로그래밍, 내장 함수 및 라이브러리에 대해 알아보았습니다. 이러한 개념들을 이해하고 활용하면 보다 효율적이고 간결한 코드를 작성할 수 있습니다. 파이썬에서의 함수는 특히 강력하며 다양한 프로그래밍 스타일과 패턴을 지원하므로, 이러한 기능들을 잘 활용하여 파이썬 프로그래밍 능력을 향상하는 것이 좋습니다.
2023.05.07 - [프로그래밍/파이썬(Python) 기초부터 ~] - [파이썬(PYTHON) : 중급] 고급 문자열 처리
반응형
'GD's IT Lectures : 기초부터 시리즈 > 파이썬(Python) 기초부터 ~' 카테고리의 다른 글
[파이썬(PYTHON) : 중급] 모듈과 패키지 고급 활용 (2) | 2023.05.09 |
---|---|
[파이썬(PYTHON) : 중급] 객체 지향 프로그래밍 (0) | 2023.05.09 |
[파이썬(PYTHON) : 중급] 고급 문자열 처리 (1) | 2023.05.07 |
[파이썬(PYTHON)] 기본적인 자료구조 - 집합 (0) | 2023.05.03 |
[파이썬(PYTHON)] 기본적인 자료구조 - 딕셔너리 (0) | 2023.05.03 |
댓글