728x90

코드를 작성하다 보면 자연스럽게 if-else 구문을 많이 사용하게 됨

조건문을 통해 로직을 처리하는 것은 필수적이지만, 조건이 복잡해지고 여러 조건이 중첩되면서 코드가 읽기 어렵고 유지보수가 힘들어지는 경우가 많음

특히, 중첩된 if-else는 코드의 가독성을 떨어뜨리는 주요 원인 중 하나임

이 글에서는 중첩된 if-else 구문을 리팩토링하는 여러 가지 기법을 소개하고, 실제로 적용할 수 있는 예시를 통해 코드의 품질을 향상시키는 방법을 정리함

Early Return 패턴

Early Return 패턴은 함수의 실행 중 특정 조건을 만족하지 않으면 일찍 반환(return)하는 방식

Early Return 패턴을 활용하면 불필요한 중첩을 방지할 수 있음

# before
def process_data(data):
    if data is not None:
        if data.is_valid():
            if data.has_permission():
                return "Processing data"
            else:
                return "No permission"
        else:
            return "Invalid data"
    else:
        return "No data"
        
 # after
 def process_data(data):
    if data is None:
        return "No data"
    if not data.is_valid():
        return "Invalid data"
    if not data.has_permission():
        return "No permission"
    
    return "Processing data"

Early Return을 사용하면 코드의 중첩을 줄여 가독성을 크게 향상시킬 수 있음

조건이 충족되지 않을 경우 빠르게 반환(Return)하면 이후 로직을 간결하게 처리할 수 있음

 

Guard Clauses 패턴

Guard Clauses는 특정 조건을 검사해 빠르게 반환하거나 예외를 던지는 패턴

이 방식은 Early Return과 유사하지만, 주로 예외 처리나 특정한 조건을 걸러내는 데 자주 사용됨

# before
def calculate_discount(price, user):
    if price > 0:
        if user.is_premium():
            if user.has_discount_coupon():
                return price * 0.7
    return price


# after
def calculate_discount(price, user):
    if price <= 0:
        raise ValueError("Price must be greater than zero")
    
    if not user.is_premium():
        return price
    
    if not user.has_discount_coupon():
        return price
    
    return price * 0.7

 

조건문을 함수로 분리

Early Return, Guard Clauses 패턴을 사용할 때 조건이 많은 경우 

각 조건을 별도의 함수로 분리해 코드의 가독성과 재사용성을 높일 수 있음

# before
def validate_user(user):
    if user.is_active:
        if user.has_subscription:
            if user.is_email_verified:
                return True
    return False


# after
def is_active_user(user):
    return user.is_active

def has_valid_subscription(user):
    return user.has_subscription

def is_email_verified(user):
    return user.is_email_verified

def validate_user(user):
    if not is_active_user(user):
        return False
    if not has_valid_subscription(user):
        return False
    if not is_email_verified(user):
        return False
    return True

 

데이터 구조를 활용해 조건 제거하기

때로는 복잡한 조건문을 데이터 구조를 사용해 간결하게 표현할 수도 있음

특히 다중 조건을 처리할 때 유용함

# before
def get_discount(user_type):
    if user_type == "premium":
        return 20
    elif user_type == "standard":
        return 10
    elif user_type == "basic":
        return 5
    else:
        return 0


# after
def get_discount(user_type):
    discounts = {
        "premium": 20,
        "standard": 10,
        "basic": 5,
    }
    return discounts.get(user_type, 0)
728x90

'Python' 카테고리의 다른 글

파이썬 클린코드  (0) 2024.04.28
파이썬 계약에 의한 디자인(Design by Contract, DbC)  (1) 2024.04.21
Python 정규 표현식 기초  (0) 2024.04.13
Python 추상클래스  (0) 2024.04.12
Python Singleton 패턴  (0) 2024.04.12
728x90

prometheus_client 라이브러리는 Prometheus와 함께 사용할 수 있는 클라이언트 라이브러리로, 애플리케이션의 메트릭을 수집하고 노출하는 데 사용됨

이 라이브러리를 통해 다양한 유형의 메트릭을 생성하고 관리할 수 있음

이 라이브러리에서 메트릭 수집을 위하여 주로 사용되는 Counter, Gauge, Histogram 클래스에 대해 알아봄

Counter

Counter는 단조 증가하는 메트릭을 나타냄

주로 이벤트의 발생 횟수를 측정하는 데 사용됨

한 번 증가하면 줄어들지 않음

from prometheus_client import Counter

# Counter 메트릭 생성
requests_total = Counter('requests_total', 'Total number of requests')

# 메트릭 증가
requests_total.inc()  # 1 증가
requests_total.inc(5)  # 5 증가

Gauge

Gauge는 값이 증가하거나 감소할 수 있는 메트릭을 나타냄

현재 온도, 메모리 사용량 등과 같이 상태를 나타내는 데 사용됨

from prometheus_client import Gauge

# Gauge 메트릭 생성
temperature = Gauge('temperature', 'Current temperature')

# 메트릭 설정 및 변경
temperature.set(25.3)  # 값 설정
temperature.inc()      # 1 증가
temperature.dec(2.3)   # 2.3 감소

Histogram

Histogram은 값의 분포를 관찰하는 데 사용됨

요청 시간, 응답 크기 등의 분포를 측정하는 데 유용함

from prometheus_client import Histogram

# Histogram 메트릭 생성
request_latency = Histogram('request_latency_seconds', 'Request latency')

# 메트릭 관찰
request_latency.observe(0.5)  # 0.5초의 지연 시간 관찰
request_latency.observe(1.2)  # 1.2초의 지연 시간 관찰

종합 예제

Counter, Gauge, Histogram을 사용하여 간단한 웹 애플리케이션에서 메트릭을 수집하고 노출하는 예제

 
from prometheus_client import Counter, Gauge, Histogram, start_http_server
import time
import random

# 메트릭 정의
REQUESTS = Counter('requests_total', 'Total number of requests')
TEMPERATURE = Gauge('temperature', 'Current temperature')
LATENCY = Histogram('request_latency_seconds', 'Request latency')

# 메트릭 수집 및 노출 시작
start_http_server(8000)

while True:
    # Counter 증가
    REQUESTS.inc()

    # Gauge 설정
    TEMPERATURE.set(random.uniform(20.0, 30.0))

    # Histogram 관찰
    latency = random.uniform(0.1, 1.0)
    LATENCY.observe(latency)

    # 대기 시간
    time.sleep(1)

결론

  • Counter: 단조 증가 메트릭
  • Gauge: 값이 증가하거나 감소할 수 있는 메트릭
  • Histogram: 값의 분포를 관찰하는 메트릭

이러한 구성 요소를 사용하여 애플리케이션의 다양한 성능 지표를 수집하고 Prometheus 서버에 노출할 수 있음

728x90
728x90

클린코드란?

클린 코드는 소프트웨어 개발에서 가독성이 높고 유지보수가 쉬운 코드를 작성하는 데 초점을 둔 개념

  • 클린 코드의 주요 특징
    • 가독성 : 다른 사람이 이해하기 쉬워야 함
    • 단순성 : 가능한 간결하고 단순해야 함
    • 테스트 용이성 : 테스트 가능한 코드를 작성하는 것이 중요함
    • 모듈화 : 코드를 작은 모듈로 분할하여 각 모듈이 독립적으로 테스트하고 유지보수 할 수 있도록 해야 함
    • 중복 최소화 : 중복을 최소화하여 일관성을 유지하고 유지보수를 용이하게 해야 함
    • 설계 패턴 활용 : 적절한 설계 패턴을 활용하여 코드의 유연성과 확장성 향상
  • 클린코드의 효과
    • 코드의 신뢰성 향상
    • 신속한 개발과 지속적인 배포 가능
    • 코드가 작성된 후에도 코드를 이해하고 수정하는 데 드는 비용을 최소화
  • 클린코드를 준수하지 않아도 되는 경우 (예외상황)
    • 다시 사용하지 않을 코드이며 좋은 품질의 코드가 아니어도 큰 무리가 없는 상황

코드 포매팅이란?

코드 포매팅은 클린 코드 작성에서 중요한 부분 중 하나

코드 포매팅은 코드의 모양과 구조를 일관되게 유지하여 가독성을 향상시키고 코드베이스의 일관성을 유지하는 데 도움을 줌

  • 코드 포매팅의 효과
    • 가독성 향상 : 일관된 들여쓰기, 공백 사용, 줄 바꿈 등은 코드를 읽는 사람이 코드를 쉽게 이해할 수 있도록 도와줌
    • 일관성 제공 : 코드베이스 내에서 일관된 스타일을 유지함으로써 여러 명의 개발자가 작업할 때 혼동을 줄이고 코드를 이해하기 쉽게 만듦
    • 버그 방지 : 올바른 코드 포매팅은 실수를 줄이고 버그를 방지하는 데 도움이 됨
    • 협업 용이성 : 일관된 코드 포매팅은 팀원 간의 코드리뷰, 협업을 용이하게 만들어 효율성을 높임
    • 자동화된 도구와 통합 : 코드 포매팅 규칙을 자동화된 도구와 통합하면 코드베이스에 일관된 스타일을 적용할 수 있어, 개발자가 수동으로 코드를 정리하는 시간과 노력을 줄여줌

파이썬에서의 코드 포매팅 PEP-8

띄어쓰기, 네이밍 컨벤션, 줄 길이 제한 등의 파이썬 코드 스타일 가이드라인을 제공

  • PEP-8 주요 권장사항
    • 들여쓰기 : 공백 4칸을 사용하여 코드 블록을 들여쓰기
    • 줄 길이 : 한 줄의 길이를 79자로 제한
    • 빈 줄 : 함수 정의와 클래스 정의 사이, 클래스 메서드 사이에 빈 줄 삽입
    • import 문 : import 문을 알파벳 순서로 그룹화하여, 각 그룹 사이에 빈 줄을 삽입
    • 공백 : 함수 정의와 호출 시 인수들 간에는 공백 제외, 연산자 주변과 쉼표 뒤에는 공백 삽입
    • 명명 규칙 :
      클래스 이름은 카멜케이스를 사용하고, 모듈 수준의 상수는 대문자와 밑줄을 사용
      함수, 변수, 메서드는 소문자로 구성하고 필요한 경우 단어 사이를 밑줄로 구분
    • 주석 : 주석은 문장의 첫 글자를 대문자로 시작하고 마침표로 끝내며, 코드와 함께 사용하는 것이 아니라면 최대한 지양
    • docstring : 모듈, 함수, 클래스에는 문서화 문자열(docstring)을 포함하여 기능과 사용법을 설명

파이썬 코드 개선/유지 도구

  • 데이터 타입 일관성 검사 도구 : mypy (annotation이 정확히 작성 되어 있어야 함)
  • 코드 품질 검사 도구 : pylint, flake8, pycodestyle(pep8)
  • 포매팅 도구 : black
728x90
728x90

계약에 의한 디자인(Design by Contract, DbC)이란?

계약에 의한 디자인은 소프트웨어 개발에서 소프트웨어 컴포넌트 간의 상호 작용을 정의하고 문서화하는 방법론 중 하나

소프트웨어 개발 과정에서 컴포넌트의 명세를 명확하게 정의함으로써 소프트웨어의 신뢰성과 유지 보수성을 향상시킴

구성요소

  • 사전조건 (precondition)
    • 함수가 실행되기 전에 참이어야 하는 조건
    • 일반적으로 파라미터의 유효성을 검사
  • 사후조건 (postcondition)
    • 함수가 실행된 후에 참이어야 하는 조건
    • 일반적으로 함수의 반환값을 검사
  • 클래스 불변식 (invairant)
    • 클래스의 인스턴스가 항상 유효한 상태를 유지해야 하는 조건
    • 모든 메서드 호출 후에도 이 조건이 유지되어야 함
    • 함수의 docstring에 불변식에 대해 문서화하는 것이 좋음
  • 부작용 (side effect)
    • 함수가 호출된 후에 함수 외부에 미치는 영향
    • 선택적으로 docstring에 언급함

파이썬에서 DbC을 구현하는 방법

  • 제어 메커니즘 추가
    • 함수, 메서드, 클래스에 사전 조건과 사후 조건을 검사하는 제어 메커니즘을 추가
    • 입력 값의 유효성을 검증하고, 함수 또는 메서드의 실행 결과를 확인할 수 있음
  • 예외 발생
    • 검사에 실패할 경우 RuntimeError, ValueError, 또는 사용자 정의 예외를 발생시켜 에러를 처리
  • assert문 사용
    • 함수나 메서드의 입력 값 검증에 assert문을 사용하여 사전 조건을 명시적으로 검사
  • 문서화
    • 함수와 메서드에는 docstrings을 활용하여 각각의 계약을 명확히 문서화
  • 타입 힌트 사용
    • typing 모듈을 활용하여 함수나 메서드의 인자와 반환 값의 타입을 명시하여 계약을 더욱 명확하게 정의
  • 코드 격리
    • 사전조건과 사후조건의 검사, 핵심 기능의 구현을 가능한 한 격리된 상태로 유지
    • 작은 함수를 생성하거나, 데코레이터를 활용하여 구현

파이썬 DbC 구현 예시

파이썬에서는 계약에 의한 디자인을 구현하기 위하여 contract 모듈을 사용할 수 있음

from contract import contract

class Calculator:
    @contract(x='int', y='int', returns='int')
    def add(self, x, y):
        """Add two integers."""
        return x + y

# Calculator 객체 생성
calc = Calculator()

# 덧셈 기능 테스트
result = calc.add(3, 5)
print("결과:", result)  # 출력: 결과: 8

# 타입이 다른 인자를 전달하는 경우
result = calc.add(3.5, 5)  # ContractNotRespected 예외 발생

위 코드에서는 contract 데코레이터를 사용하여 add 메서드의 계약을 정의함

이 계약은 x와 y가 모두 정수인 경우에만 유효하며, 반환 값 또한 정수여야 함

만약 이 계약을 위반하면 ContractNotRespected 예외가 발생

이와 같이 DbC를 활용하면 개발자는 코드의 의도를 명확히 정의할 수 있고, 이로 인해 코드의 가독성과 유지 보수성이 향상됨

728x90

'Python' 카테고리의 다른 글

중첩된 if-else 구문 리팩토링하는 방법  (0) 2024.08.16
파이썬 클린코드  (0) 2024.04.28
Python 정규 표현식 기초  (0) 2024.04.13
Python 추상클래스  (0) 2024.04.12
Python Singleton 패턴  (0) 2024.04.12
728x90

정규표현식이란

정규표현식(Regular Expression)은 문자열에서 패턴을 찾거나 특정 문자열을 대체하거나 추출할 때 사용하는 도구

예를 들어, 이메일 주소를 찾거나 특정한 형식의 날짜를 추출하는 등의 작업에 유용하게 사용될 수 있음

파이썬 주요 메타문자

메타문자는 정규표현식을 나타내는 기초 문자로, 특별한 의미를 가진 문자를 의미

정규 표현식에 다음과 같은 메타 문자를 사용하면 특별한 의미를 갖게 됨 

. ^ $ * + ? { } [ ] \ | ( )
  • . : 문자 하나를 의미
  • [] : 대괄호 안에 있는 문자 중 하나를 의미
    정규 표현식이 [abc]라면 이 표현식은 ‘a, b, c 중 한 개의 문자와 매치’를 뜻함
    "a", "before"는 각각 a, b가 포함되므로 정규식 [abc]와 어떻게 매치되고, "doll"는 a,b,c중 어느 하나도 포함하지 않으므로 매치되지 않음
  • \d : 숫자를 의미,  [0-9]와 동일한 표현식
  • \w : 알파벳이나 숫자를 의미,  [a-zA-Z0-9_]와 동일한 표현식
  • \W : 문자+숫자가 아닌 문자를 의미, [^a-zA-Z0-9_]와 동일한 표현식
  • \s : 공백 문자를 의미, [ \t\n\r\f\v]와 동일한 표현식
  •  \S : 화이트스페이스 문자가 아닌 것, [^ \t\n\r\f\v]와 동일한 표현식
  • * : 앞의 패턴이 0번 이상 반복되는 것을 나타냄
    정규표현식이 ca*t이라면 ct, cat, caat 등이 모두 매치됨
  • + : 앞의 패턴이 1번 이상 반복되는 것을 나타냄
    정규표현식이 ca+t이라면 ct는 a가 0번이므로 매치되지 않음
    cat, caat 등이 매치됨

  • ? : 앞의 패턴이 0번 또는 1번 등장하는 것을 나타냄
    정규표현식이 ab?c이면 a + b가 있어도 되고 없어도 되지만 c는 필수
  • {} : 중괄호 안에 숫자를 넣어 반복 횟수를 지정할 수 있음
    정규표현식이 ca{2}t 라면 c + a를_반드시_2번_반복하고 t는 필수
    caat과 매치됨

파이썬 정규 표현식 모듈 re

파이썬은 정규 표현식을 지원하기 위해 re(regular expression) 모듈을 제공함

 

1. 컴파일 객체 생성

import re
p = re.compile('[a-z]+')

 

2. 정규표현식을 이용한 문자열 검색

match() 문자열의 처음부터 정규식과 매치되는지 조사
search() 문자열 전체를 검색하여 정규식과 매치되는지 조사
findall() 정규식과 매치되는 모든 문자열을 리스트로 리턴
finditer() 정규식과 매치되는 모든 문자열을 반복 가능한 객체로 리턴
# match : 문자열의 처음부터 정규식과 매치되는지 조사
# 매치되는 문자열은 match 객체 리턴
m = p.match("python")
print(m) # re.Match object; span=(0, 6), match='python'>

# 매치되지 않는 문자열은 None 리턴
m = p.match("3 python")
print(m) # None
# search : 문자열 전체를 검색하여 정규식과 매치되는지 조사
# 일치하는 문자열
m = p.search("python")
print(m)
<re.Match object; span=(0, 6), match='python'>

# 중간부터 일치하는 문자열
m = p.search("3 python")
print(m)
<re.Match object; span=(2, 8), match='python'>
# findall : 정규식과 매치되는 모든 문자열을 리스트로 리턴
result = p.findall("life is too short")
print(result)
['life', 'is', 'too', 'short']
# finditer : 정규식과 매치되는 모든 문자열을 반복 가능한 객체로 리턴
result = p.finditer("life is too short")
print(result) 
# 결과
# <callable_iterator object at 0x01F5E390>
for r in result: print(r)
# 결과
# ...
# <re.Match object; span=(0, 4), match='life'>
# <re.Match object; span=(5, 7), match='is'>
# <re.Match object; span=(8, 11), match='too'>
# <re.Match object; span=(12, 17), match='short'>

 

3. match 객체의 메서드

group 매치된 문자열을 리턴
start 매치된 문자열의 시작 위치를 리턴
end 매치된 문자열의 끝 위치를 리턴
span 매치된 문자열의 (시작, 끝)에 해당하는 튜플을 리턴
m = p.match("python")
m.group() # 'python'
m.start() # 0
m.end() # 6
m.span() # (0, 6)

참고

https://wikidocs.net/4308

728x90

'Python' 카테고리의 다른 글

파이썬 클린코드  (0) 2024.04.28
파이썬 계약에 의한 디자인(Design by Contract, DbC)  (1) 2024.04.21
Python 추상클래스  (0) 2024.04.12
Python Singleton 패턴  (0) 2024.04.12
Python 날짜 시간 데이터 다루기 (feat. pandas)  (1) 2024.04.12
728x90

추상화객체 지향 프로그래밍의 핵심 개념 중 하나

추상화는 객체들 간의 공통된 특성을 추출하여 추상 클래스로 정의함으로써 코드의 재사용성과 유지보수성을 향상하는 방법

파이썬은 객체 지향 프로그래밍을 지원하는 강력한 언어로, 추상 클래스를 이용하여 추상화를 구현할 수 있음

추상클래스란

추상 클래스는 하나 이상의 추상 메서드를 포함하는 클래스

추상 메소드는 구현이 정의되어 있지 않은 메서드로, 서브 클래스에서 반드시 구현되어야 함

추상 클래스는 직접적으로 인스턴스화할 수 없으며, 서브 클래스에서 추상 메서드를 구현한 후에야 비로소 인스턴스화할 수 있음

파이썬에서 추상클래스를 정의하는 방법

파이썬에서 추상 클래스를 정의하려면 abc (Abstract Base Classes) 모듈을 사용

이 모듈은 추상 클래스와 추상 메서드를 정의하고 사용하는 데 필요한 기능을 제공함

  • 추상 클래스(Abstract Base Classes) 정의
    abc 모듈을 사용하여 추상 클래스를 정의할 수 있음
    추상 클래스는 하나 이상의 추상 메소드를 포함하며, 이러한 추상 메서드는 서브 클래스에서 반드시 구현되어야 함
  • 추상 메소드(Abstract Methods) 정의
    추상 메소드는 구현이 정의되어 있지 않은 메서드로, 추상 클래스에서 선언됨
    서브 클래스에서는 추상 메소드를 반드시 구현해야 함
  • @abstractmethod 데코레이터
    abc 모듈에서 제공하는 abstractmethod 데코레이터를 사용하여 메서드를 추상 메서드로 선언할 수 있음
    이를 통해 해당 메소드가 반드시 구현되어야 함을 명시적으로 나타낼 수 있음

예를 들어 동물의 추상 개념을 모델링하고자 한다고 가정하면, 모든 동물은 소리를 낼 수 있지만 각 동물의 소리는 다름

이를 추상 클래스를 통해 구현하면 아래와 같음

from abc import ABC, abstractmethod

class Animal(ABC):
    @abstractmethod
    def make_sound(self):
        pass

class Dog(Animal):
    def make_sound(self):
        return "Woof!"

class Cat(Animal):
    def make_sound(self):
        return "Meow!"

dog = Dog()
print(dog.make_sound())  # 출력: Woof!

cat = Cat()
print(cat.make_sound())  # 출력: Meow!

 

위의 예시에서 Animal 클래스는 추상 클래스로, make_sound() 메소드가 추상 메서드로 정의되어 있음

각 동물 종류를 나타내는 DogCat 클래스는 Animal 클래스를 상속받고, 추상 메서드인 make_sound()를 구현함

추상 클래스의 장점

  • 유연성
    추상 클래스를 사용하면 상속을 통해 기본적인 동작을 공유하면서 각각의 클래스에서 독립적인 특징을 구현 가능
  • 코드 재사용성
    공통된 동작을 추상 클래스에 정의함으로써 코드의 재사용성을 높일 수 있음
  • 명확한 인터페이스 제공
    추상 클래스는 서브 클래스가 반드시 구현해야 할 메서드를 정의하므로 코드의 명확성을 제공함

파이썬의 추상 클래스를 효과적으로 활용하면 객체 지향 프로그래밍의 장점을 최대한 활용할 수 있음

추상화를 통해 코드의 유지보수성을 향상하고, 확장 가능한 소프트웨어를 개발할 수 있음

728x90
728x90

싱글턴 패턴이란

일반적으로 클래스가 정의되면 클래스로부터 여러 개의 객체를 생성할 수 있음

하지만 특수한 경우 객체를 하나만 생성하도록 제한하는게 유용한 경우가 있음

 

싱글턴(Singleton) 패턴은 소프트웨어 디자인 패턴 중 하나로, 클래스의 인스턴스를 단 하나만 생성하고 그 인스턴스에 대한 전역적인 접근을 제공하는 패턴

사용자가 여러 번 객체 생성을 하더라도 클래스로부터 오직 하나의 객체만 생성됨

이 패턴은 일반적으로 다음과 같은 상황에서 사용됨

  • 클래스의 인스턴스가 오직 하나만 존재해야 하는 경우
  • 클래스의 인스턴스가 공유되어야 하는 경우
  • 전역 객체를 사용하여 리소스를 공유하고 관리해야 하는 경우

싱글턴 패턴을 활용하면 유용한 상황

  • 로깅 시스템
    로깅은 어플리케이션 개발 및 유지보수에 있어서 매우 중요한 부분
    로깅 시스템을 구현할 때 여러 곳에서 동시에 로그 파일에 접근하고 기록할 수 있지만, 로그 파일 자체는 하나의 인스턴스만 있으면 충분함
    이런 경우에 싱글턴 패턴을 사용하여 로그 인스턴스를 공유하고 여러 곳에서 접근할 수 있음
  • 캐싱
    캐싱은 데이터나 계산 결과를 임시로 저장하여 다음에 같은 데이터나 계산 결과가 필요할 때 다시 계산하는 것을 방지함
    예를 들어, 데이터베이스 쿼리 결과를 캐싱하여 동일한 쿼리가 여러 번 실행되는 것을 방지할 수 있음
    이때 캐시 객체는 여러 곳에서 공유되어야 하기 때문에, 싱글턴 패턴을 사용하여 캐시 객체를 구현할 수 있음
  • 설정 관리
    어플리케이션의 설정 정보는 전역적으로 접근되어야 하며, 한 번 로드되면 여러 곳에서 공유되어야 함
    따라서 설정 관리자 객체를 싱글턴으로 구현하여 설정 정보에 대한 중복 로드를 방지하고 설정 정보에 대한 일관성을 유지할 수 있음
  • 데이터베이스 연결 풀
    데이터베이스 연결은 비용이 많이 드는 작업이므로, 연결을 재사용하여 성능을 향상시키는 것이 중요함
    데이터베이스 연결 풀을 구현할 때 싱글턴 패턴을 사용하여 연결을 관리하고 재사용할 수 있음
  • 응용 프로그램 상태 관리
    응용 프로그램의 상태 정보는 여러 곳에서 공유되어야 하며, 상태 정보가 한 곳에서 변경되면 모든 곳에서 변경된 상태를 반영해야 함
    이런 경우에 상태 관리자 객체를 싱글턴으로 구현하여 상태 정보를 효율적으로 관리할 수 있음

파이썬에서의 싱글턴 패턴

파이썬에서 싱글턴 패턴을 구현하는 가장 일반적인 방법은 __new__ 메서드를 이용하여 객체 생성을 제어하는 것

__new__ 메서드는 클래스의 인스턴스를 생성하는 역할을 담당하며, 해당 클래스의 인스턴스가 생성되기 전에 호출됨

따라서 __new__ 메서드를 사용하여 인스턴스를 생성할 때 이미 생성된 인스턴스가 있는지 확인하고, 있다면 해당 인스턴스를 반환하도록 구현할 수 있음

class Singleton(object):
    def __new__(cls, *args, **kwargs):
        # 객체가 한 번도 생성되지 않은 경우에만 생성
        if not hasattr(cls, "_instance"):
            print("__new__ is called\n")
            cls._instance = super().__new__(cls, *args, **kwargs)
        return cls._instance

    def __init__(self, data):
        cls = type(self)
        # 초기화가 한 번도 호출되지 않은 경우에만 초기화 진행
        if not hasattr(cls, "_init"):
            print("__init__ is called\n")
            self.data = data
            cls._init = True


s1 = Singleton(3)
s2 = Singleton(4)
print(s1.data) # 3
print(s2.data) # 3 (s1에서 초기화 했으므로 초기화 함수 pass함)

 

728x90
728x90

파이썬에서는 데이터 분석 및 시계열 데이터 처리를 위해 pandas 라이브러리를 사용함

pandasTimestamp 클래스는 날짜와 시간 데이터를 효과적으로 다룰 수 있도록 해줌

날짜, 시간 생성

import pandas as pd

현재_시간 = pd.Timestamp.now()
print("현재 시간:", 현재_시간)

특정_시간 = pd.Timestamp(2024, 4, 12, 10, 30, 0)
print("특정 시간:", 특정_시간)

날짜 및 시간 형식화

import pandas as pd

현재_시간 = pd.Timestamp.now()
형식화된_시간 = 현재_시간.strftime('%Y-%m-%d %H:%M:%S')
print("형식화된 시간:", 형식화된_시간)

%Y, %m, %d, %H, %M, %S는 각각 연도, 월, 일, 시, 분, 초를 나타내는 포맷 문자열

timedelta를 사용한 날짜 및 시간 연산

import pandas as pd

현재_시간 = pd.Timestamp.now()
시간_차이 = pd.Timedelta(days=3, hours=5, minutes=30)
미래_시간 = 현재_시간 + 시간_차이
과거_시간 = 현재_시간 - 시간_차이

print("미래 시간:", 미래_시간)
print("과거 시간:", 과거_시간)

Pandas를 이용한 시계열 데이터 처리 예시

cansim.csv
0.01MB

import pandas as pd

# 데이터 로드
데이터 = pd.read_csv('./cansim.csv')

# 날짜 및 시간 열 처리
데이터['adjustments'] = pd.to_datetime(데이터['adjustments'])

# 데이터 필터링
특정_기간 = (데이터['adjustments'] > '1991-10-31') & (데이터['adjustments'] <= '1992-02-29')
필터링된_데이터 = 데이터[특정_기간]
print(필터링된_데이터)


# 시계열 데이터 시각화
import matplotlib.pyplot as plt

plt.plot(데이터['adjustments'], 데이터['seasonally_adjusted'])
plt.xlabel('adjustments')
plt.ylabel('seasonally adjusted')
plt.title('Time Series Data Visualization')
plt.show()
더보기

실행결과

 

   adjustments  unadjusted  seasonally_adjusted
10  1991-11-30    16237366             15662790
11  1991-12-31    18381340             15349625
12  1992-01-31    13084963             15477875
13  1992-02-29    12773972             15513022

728x90

'Python' 카테고리의 다른 글

Python 추상클래스  (0) 2024.04.12
Python Singleton 패턴  (0) 2024.04.12
Python 날짜 시간 다루기 (feat. datetime)  (0) 2024.04.12
[작성중] Python 문서화 (feat. sphinx)  (0) 2024.04.12
Python 문서화 (feat. PEP 257)  (0) 2024.04.11
728x90

파이썬의 datetime 모듈을 이용하면 다양한 날짜와 시간 처리 작업을 손쉽게 수행할 수 있음

이를 통해 날짜와 시간을 생성하고 형식화하며, 연산하는 등의 작업을 효과적으로 처리할 수 있음

날짜, 시간 생성

이 모듈을 사용하여 현재 시간을 가져오거나 특정 날짜와 시간을 생성할 수 있음

import datetime

현재_시간 = datetime.datetime.now()
print("현재 시간:", 현재_시간)

특정_시간 = datetime.datetime(2024, 4, 12, 10, 30, 0)  # 년, 월, 일, 시, 분, 초
print("특정 시간:", 특정_시간)

날짜 및 시간 형식화

import datetime

현재_시간 = datetime.datetime.now()
형식화된_시간 = 현재_시간.strftime('%Y-%m-%d %H:%M:%S')

print("형식화된 시간:", 형식화된_시간)

%Y, %m, %d, %H, %M, %S는 각각 연도, 월, 일, 시, 분, 초를 나타내는 포맷 문자열

timedelta를 이용한 날짜 및 시간 연산

import datetime

시간_차이 = datetime.timedelta(days=3, hours=5, minutes=30)
현재_시간 = datetime.datetime.now()
미래_시간 = 현재_시간 + 시간_차이
과거_시간 = 현재_시간 - 시간_차이

print("미래 시간:", 미래_시간)
print("과거 시간:", 과거_시간)

 

 

728x90

'Python' 카테고리의 다른 글

Python Singleton 패턴  (0) 2024.04.12
Python 날짜 시간 데이터 다루기 (feat. pandas)  (1) 2024.04.12
[작성중] Python 문서화 (feat. sphinx)  (0) 2024.04.12
Python 문서화 (feat. PEP 257)  (0) 2024.04.11
Python ZeroMQ  (0) 2024.04.11
728x90

Sphinx는 Python 프로젝트의 문서화를 위한 강력한 도구

주로 코드 기반 문서화에 사용되며, Python 코드의 docstrings과 함께 사용하여 API 문서를 생성하는 데 특히 유용함

프로젝트의 사용법, 모듈, 클래스, 함수 등에 대한 자동화된 문서를 생성할 수 있음

sphinx를 이용하여 만든 docs를 readthedocs.org에 배포하면 docs를 온라인에 공개 가능함

많은 오픈소스는 위와 같은 방법으로 docs를 공개하고 있음

 

sphinx를 이용한 docs 생성 및 배포 방법은 아래 블로그에서 쉽게 설명하고 있음

https://hooni-playground.com/1101/

 

Sphinx / Read-the-Docs를 통한 Python Project 문서화 | Hooni's Playground

개발과 문서가 따로노니 신경쓸 것이 두 배로 생긴다. 이에 소스코드로부터 개발문서를 만들어보기로 했다. Sphinx란 Python을 위한 문서화 라이브러리로 소스코드로부터 문서(html, LaTeX 등)를 정적

hooni-playground.com

 

sphinx

728x90

+ Recent posts