본문 바로가기
파이썬/파이썬의 디자인 패턴 공부

02 싱글톤 패턴 & 게으른 초기화

by David.Ho 2023. 12. 21.
728x90
반응형
"게으른 개발자"의 유래

한국에서 익히 사용되는 개발 언어(?)이다.

'긍정적인 의미'로는
 일부 개발자들은 혁신적이고 효율적인 방법을 찾기 위해 노력하면서, 기술적인 문제를 해결하는 데 시간을 들이고 고민하는 모습을 기리는 것이다.
 개발 작업에서 늘 새로운 방법과 해결책을 찾기 위해 고심하고 실험하는 과정에서 '게으름'이라는 말은 실제로 창의적인 사고와 혁신을 이끌어냈다는 관점에서 긍정적으로 받아들여진다.

반면,

'부정적인 의미'로는
개발자들이 일을 귀찮아하거나 적극적으로 문제를 해결하지 않는다는 부정적인 해석으로도 사용될 수 있다. 이는 느슨하거나 무관심한 태도로 인해 일정을 맞추지 않거나 문제에 대처하지 않는 상황을 비판하는 의미로 사용될 수 있다.

 

게으른 초기화(Lazy instantiation):

 싱글톤 패턴을 기반의 초기화 방식입니다.

개발을 하다보면 모듈을 import할 때 아직 필요하지 않은 시점에 실수로 객체를 미리 생성하는 경우가 있습니다.

이를 방지하기 위해 게으른 초기화(Lazy instantiation) 2가지의 핵심 정책(?)이 있습니다.

 

1) 인스턴스를 꼭 필요할 때 생성한다.
2) 사용할 수 있는 리소스가 제한적인 경우, 객체가 꼭 필요한 시점에 객체를 생성한다.

코드 구현

 

@classmethod이란?
파이썬 클래스에서 특별한 유형의 메서드를 나타내는데 사용되는 데코레이터이다.
클래스 메서드(class method)로 정의된 메서드는 해당 클래스의 인서턴스가 아닌 클래스 자체에 연관된 작업을 수행할 수 있다.

'@classmethod' 데코레이터를 사용하여 선언된 메서드는 첫 번째 매개변수로 클래스 자신을 가리키는 'cls'를 받는다. 보통 이러한 메서드들은 클래스 레벨정보를 조작하거나 클래스 변수에 접근하기 위해 사용된다.

[예제 코드]
class MyClass:
    class_variable = 10

    def __init__(self, x):
        self.x = x

    @classmethod
    def from_string(cls, string):
        # 클래스 메서드로 객체를 생성하여 반환
        return cls(int(string))

    @classmethod
    def update_class_variable(cls, value):
        # 클래스 변수를 업데이트하는 클래스 메서드
        cls.class_variable = value

# 클래스 메서드를 사용하여 객체 생성
obj = MyClass.from_string("5")
print(obj.x)  # 출력: 5

# 클래스 메서드를 사용하여 클래스 변수 업데이트
MyClass.update_class_variable(20)
print(MyClass.class_variable)  # 출력: 20​

위의 예제에서
(1) 'from_string' 메서드는 문자열을 받아 정수로 변환하여 MyClass의 인스턴스를 생성한다.
(2) 'update_class_variable' 메서드는 클래스 변수 class_variable을 업데이트하는 데 사용된다.

클래스 메서드는 인스턴스 변수에 접근할 수 없으며, 대신 클래스 변수에 접근하거나 다룰 때 사용된다. 또한 클래스 메서드는 일반적으로 @classmethod 데코레이터를 사용하여 정의되며, 첫 번째 매개변수로 클래스 자신을 가리키는 cls를 받는다.

 

데코레이터(Decorator)란?
파이썬에서 함수나 클래스의 기능을 수정하거나 확장하기 위한 강력한 도구이다. 데코레이터는 기존의 함수나 클래스를 수정하지 않고 추가적인 기능을 제공하며, 코드의 재사용성과 가독성을 높인다.

@데코레이터이름과 같은 형태로 사용하며, 함수(메서드)를 장식한다.

데코레이터는 '@'기호를 사용하여 정의되며, 함수나 클래스 위에 선언된다. 이는 일반적으로 함수를 다른 함수의 인자로 받아 내부에서 해당 함수를 수정하거나 감싸는(wrapper) 역할을 한다.

[예제 코드: 함수의 실행 전후에 시간을 측정하여 출력하는 데코레이터를 정의]
import time

# 데코레이터 함수 정의
def measure_time(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f"실행 시간: {end_time - start_time}초")
        return result
    return wrapper

# 데코레이터를 함수에 적용
@measure_time
def do_something():
    # 여기서 시간이 걸리는 작업을 수행한다 가정
    time.sleep(2)
    print("작업 완료")

# 함수 실행
do_something()​

 

위의 코드에서
(1) measure_time 데코레이터는 실행 시간을 측정하는 역할을 한다. @measure_time이라고 표시된 부분은 do_something 함수를 measure_time 데코레이터에 전달하여 감싸게 된다.
(2) 그 결과, do_something 함수가 호출될 때마다 데코레이터에 의해 시간 측정이 수행된다.

데코레이터를 사용하면 함수나 클래스의 기능을 수정하거나 확장할 수 있으며, 코드의 재사용성과 가독성을 높일 수 있다. 이러한 특성은 파이썬에서 함수형 프로그래밍과 메타프로그래밍을 지원하는데 큰 장점으로 작용한다.

 

if not 사용
- 'if not' 구문은 조건을 부정하는 데 사용되는 파이썬의 키워드이다.
- 'not' 키워드는 뒤에 오는 조건식의 결과를 부정한다.


기본적으로 'if'문은 조건이 참(True)일 때 코드 블록을 실행하며, 때로는 조건이 거짓(False)일 때 특정 코드 블록을 실행하고자 할 때가 있다. 이때 'not' 키워드를 사용하여 조건을 부정할 수 있다.

[예제 코드]
x = 10

# x가 5가 아닌 경우에 코드 블록 실행
if not x == 5:
    print("x는 5가 아닙니다.")

# 출력: x는 5가 아닙니다.​

위의 예시에서 not 키워드는 x == 5 조건을 부정하여 x가 5가 아닐 때 코드 블록을 실행한다. 이는 x가 5가 아니라는 것을 의미한다.

## 빈 리스트 예제
my_list = []

# my_list가 비어있지 않은 경우에 코드 블록 실행
if not my_list:
    print("리스트가 비어있습니다.")
else:
    print("리스트에 요소가 있습니다.")

# 출력: 리스트가 비어있습니다.​

'not my_list' 는 'my_list' 가 비어있지 않다는 것을 확인하여, 리스트에 요소가 없는 경우를 체크하는데 사용된다.
 만약 리스트에 요소가 있다면
not을 사용하지 않았을 때와는 반대로 if 조건문은 참이 되어 else 블록이 실행된다.

728x90
반응형

댓글