파이썬의 부작용 | Side Effect in Python
👀 파이썬의 부작용(Side Effect in Python)을 알아봅시다.
파이썬의 부작용 | Side Effect in Python
KEYWORDS
파이썬, Python, 파이썬의 부작용, Python Side Effect
Side Effect in Python
- 함수가 리턴 값, 함수의 상태, 또는 전역 프로그램 상태(Global Program State)를 변경하는 모든 작업을 의미합니다.
- 전역/정적 변수 수정, 원본 객체의 변경, 콘솔 출력 생성, 파일 및 데이터베이스 쓰기가 포함됩니다.
이러한 동작은 추적 및 수정이 어려운 버그를 발생시킬 수 있습니다.
- Side Effect가 있는 함수
1
2
3
4
5
6
7
8
# Python side effect example
def add_element(data, element):
data.append(element)
return data
my_list = [1, 2, 3]
print(add_element(my_list, 4)) # Output: [1, 2, 3, 4]
print(my_list) # Output: [1, 2, 3, 4]
- Side Effect가 없는 함수
- 동일한 입력에 대해 항상 동일한 출력을 생성해야 합니다.
- Pure Function ㅣ Side Effect가 없는 함수로, 동일한 입력에 대해 항상 동일한 출력을 생성해야 합니다.
1
2
3
4
5
6
7
8
9
# Python pure function example
def add_element_pure(data, element):
new_list = data.copy()
new_list.append(element)
return new_list
my_list = [1, 2, 3]
print(add_element_pure(my_list, 4)) # Output: [1, 2, 3, 4]
print(my_list) # Output: [1, 2, 3]
Decorator로 Side Effect 제어하기
- 함수나 클래스를 래핑하여 소스 코드를 수정하지 않고도 실행 전후에 동작을 추가할 수 있어야 합니다.
- 원본 데이터를 그대로 유지하며 데이터 복사본을 사용하도록 보장해야 합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def no_side_effects_decorator(func):
def wrapper(*args, **kwargs):
data_copy = args[0].copy() # create a copy of the data
return func(data_copy, *args[1:], **kwargs)
return wrapper
# 함수를 `no_side_effects_decorator` 래핑
@no_side_effects_decorator
def add_element(data, element):
data.append(element)
return data
my_list = [1, 2, 3]
print(add_element(my_list, 4)) # Output: [1, 2, 3, 4]
print(my_list) # Output: [1, 2, 3]
불변 데이터 구조
- 불변 객체는 생성된 후에는 변경이 불가능하므로 Side Effect를 방지할 수 있어야 합니다.
- 불변 데이터 구조를 사용하면 데이터를 수정하는 작업 시 새로운 객체를 생성해야 합니다.
- 불변 데이터 구조 예시 ㅣ Tuples, Strings, Frozensets
ex. Tensorflow tf.function
Decorator
1
2
3
4
5
6
7
8
9
@tf.function
def get_MSE(y_true, y_pred):
print("Calculating MSE!")
sq_diff = tf.pow(y_true - y_pred, 2)
return tf.reduce_mean(sq_diff)
error = get_MSE(y_true, y_pred)
error = get_MSE(y_true, y_pred)
error = get_MSE(y_true, y_pred)
# 한 번만 출력됨 Calculating MSE!
print
문은 함수가 원래 코드를 실행하면서 Graph를 생성할 때 실행됩니다.- Graph는 추적(Tracing) 과정에서 생성되며, 이후 실행되는 모든 호출에서는 Python 코드가 다시 실행되지 않습니다.
1
2
3
# Globally set everything to run eagerly to force eager execution.
tf.config.run_functions_eagerly(True)
(...)
Calculating MSE! Calculating MSE! Calculating MSE!
- Eager/Graph Execution 모두에서 값을 출력하려면
tf.print
를 사용해야 합니다.
References
This post is licensed under CC BY 4.0 by the author.