목차
유형 힌트가 왜 중요한가요?
PyDIT란 무엇인가요?
백엔드 개발 파이썬 튜토리얼 Python에서 타이핑이 미치는 영향

Python에서 타이핑이 미치는 영향

Jan 16, 2025 pm 10:13 PM

O impacto da tipagem no python

Python 버전 3.5에는 코드를 더 읽기 쉽게 만들고 개발자가 서로의 코드를 쉽게 이해할 수 있도록 '유형 힌트'가 도입되었습니다.

유형 힌트가 왜 중요한가요?

Java, C 등 강형 언어에서는 종속성 역전(DI - dependency Inversion)이 중요한 기술이지만 약형 언어에서는 구현하기 어렵습니다.

종속성 역전의 핵심 아이디어는 클래스가 특정 구현에 의존하지 않고 추상화에 의존해야 한다는 것입니다. 추상화(인터페이스 또는 추상 클래스)는 상대적으로 안정적인 계약이기 때문입니다.

나쁜 예:

class GasStation:
    def fill_tank(car, amount):
        car.fill(amount)
로그인 후 복사

이 예에서 주유소에서는 자동차에 주유만 할 수 있습니다. 설상가상으로 fill_tank 함수에는 정의된 유형이 없으므로 모든 값이 전달될 수 있으며 오류는 런타임에만 발견됩니다.

좋은 예:

from typing import Protocol

class Vehicle(Protocol):
    def fill(amount: int) -> None:
        ...
class GasStation:
    def fill_tank(vehicle: Vehicle, amount: int) -> None:
        vehicle.fill(amount)
로그인 후 복사

이 예에서는 먼저 추상 클래스 Vehicle를 정의합니다(typing.Protocol 사용). GasStationfill_tank 기능은 더 이상 특정 자동차 클래스에 의존하지 않고 Vehicle 인터페이스에 의존하므로 더욱 일반화되고 fill 메서드를 구현하는 모든 차량에 연료를 공급할 수 있습니다.

PyDIT란 무엇인가요?

Python의 유형 힌트 시스템을 활용하여 PyDIT(Python 종속성 주입 with 유형)라는 종속성 반전 사용을 단순화하는 라이브러리를 만들었습니다.

사용자 데이터를 저장하기 위한 데이터베이스 인터페이스가 필요하다고 가정해 보겠습니다. PostgreSQL, MySQL, OracleDB, 인메모리 데이터베이스 또는 NoSQL 데이터베이스를 사용하든 데이터베이스 연결 클래스를 구현하고 레코드 읽기, 쓰기 및 삭제 기능을 제공해야 합니다. .

from time import sleep
from typing import TypedDict
from typing_extensions import override
from uuid import UUID
from src.configs.di import pydit
from src.adapters.repositories.interfaces.user import UserRepository
from src.constants.injection import MEMORY_REPOSITORY_CONFIG_TOKEN
from src.domain.user.models.user import UserModel


class ConfigType(TypedDict):
    delay: int


class MemoryUserRepository(UserRepository):

    __users: dict[UUID, UserModel] = {}

    def __init__(self):
        self.__delay = self.config.get("delay", 0.2)

    @pydit.inject(token=MEMORY_REPOSITORY_CONFIG_TOKEN)
    def config(self) -> ConfigType:  # TODO: supress return type error
        pass

    @override
    def get_by_id(self, *, id_: UUID) -> UserModel:
        sleep(self.__delay)

        user = self.__users.get(id_)

        if user is None:
            raise ValueError("User not found")

        return user

    @override
    def save(self, *, data: UserModel) -> None:
        sleep(self.__delay)
        self._check_pk_conflict(pk=data.id)

        self.__users[data.id] = data

    @override
    def list_(self) -> list[UserModel]:
        return list(self.__users.values())

    def _check_pk_conflict(self, *, pk: UUID) -> None:
        if pk not in self.__users:
            return

        raise ValueError("Primary key conflicts: DB alrady has a user with this ID")
로그인 후 복사

코드가 데이터베이스 기술과 아무 관련이 없는지 확인하려면 모든 데이터베이스 클래스가 따라야 하는 인터페이스를 정의하세요.

from abc import abstractmethod
from typing import Protocol
from uuid import UUID
from src.domain.user.models.user import UserModel


class UserRepository(Protocol):
    @abstractmethod
    def get_by_id(self, *, id_: UUID) -> UserModel:
        pass

    @abstractmethod
    def save(self, *, data: UserModel) -> None:
        pass

    @abstractmethod
    def list_(self) -> list[UserModel]:
        pass
로그인 후 복사

다음으로 주입을 위한 종속성을 초기화합니다.

from src.adapters.repositories.in_memory.user import MemoryUserRepository
from src.constants.injection import MEMORY_REPOSITORY_CONFIG_TOKEN
from .di import pydit
from .get_db_config import get_db_config


def setup_dependencies():
    pydit.add_dependency(get_db_config, token=MEMORY_REPOSITORY_CONFIG_TOKEN)
    pydit.add_dependency(MemoryUserRepository, "UserRepository")
로그인 후 복사

마지막으로 사용자를 생성하는 모듈에 종속성을 삽입합니다.

from typing import cast
from src.adapters.repositories.interfaces.user import UserRepository
from src.configs.di import pydit
from src.domain.user.models.create_user import CreateUserModel
from src.domain.user.models.user import UserModel
from src.domain.user.services.create import CreateUserService
from src.domain.user.services.list import ListUsersService


class UserModule:
    @pydit.inject()
    def user_repository(self) -> UserRepository:
        return cast(UserRepository, None)

    def create(self, data: CreateUserModel) -> None:
        CreateUserService(self.user_repository).execute(data)

    def list_(self) -> list[UserModel]:
        return ListUsersService().execute()
로그인 후 복사

종속성은 속성으로 주입되며 self 또는 module.user_repository 을 통해 액세스할 수 있습니다.

이 예는 간단하지만 PyDIT는 다양한 프로젝트 구성, 코드 추상화 및 SOLID 원칙 시나리오에 적용될 수 있습니다. 코드를 시도하고 기여해 주셔서 감사합니다!

코드 저장소: Github
LinkedIn: Marcelo Almeida(MrM4rc)
PyPI: python-pydit

위 내용은 Python에서 타이핑이 미치는 영향의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

Video Face Swap

Video Face Swap

완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

중간 독서를 위해 Fiddler를 사용할 때 브라우저에서 감지되는 것을 피하는 방법은 무엇입니까? 중간 독서를 위해 Fiddler를 사용할 때 브라우저에서 감지되는 것을 피하는 방법은 무엇입니까? Apr 02, 2025 am 07:15 AM

Fiddlerevery Where를 사용할 때 Man-in-the-Middle Reading에 Fiddlereverywhere를 사용할 때 감지되는 방법 ...

10 시간 이내에 프로젝트 및 문제 중심 방법에서 컴퓨터 초보자 프로그래밍 기본 사항을 가르치는 방법? 10 시간 이내에 프로젝트 및 문제 중심 방법에서 컴퓨터 초보자 프로그래밍 기본 사항을 가르치는 방법? Apr 02, 2025 am 07:18 AM

10 시간 이내에 컴퓨터 초보자 프로그래밍 기본 사항을 가르치는 방법은 무엇입니까? 컴퓨터 초보자에게 프로그래밍 지식을 가르치는 데 10 시간 밖에 걸리지 않는다면 무엇을 가르치기로 선택 하시겠습니까?

Inversiting.com의 크롤링 메커니즘을 우회하는 방법은 무엇입니까? Inversiting.com의 크롤링 메커니즘을 우회하는 방법은 무엇입니까? Apr 02, 2025 am 07:03 AM

Investing.com의 크롤링 전략 이해 많은 사람들이 종종 Investing.com (https://cn.investing.com/news/latest-news)에서 뉴스 데이터를 크롤링하려고합니다.

Python 3.6 피클 파일로드 오류 modulenotfounderRor : 피클 파일 '__builtin__'를로드하면 어떻게해야합니까? Python 3.6 피클 파일로드 오류 modulenotfounderRor : 피클 파일 '__builtin__'를로드하면 어떻게해야합니까? Apr 02, 2025 am 06:27 AM

Python 3.6에 피클 파일 로딩 3.6 환경 오류 : ModulenotFounderRor : nomodulename ...

SCAPY 크롤러를 사용할 때 파이프 라인 파일을 작성할 수없는 이유는 무엇입니까? SCAPY 크롤러를 사용할 때 파이프 라인 파일을 작성할 수없는 이유는 무엇입니까? Apr 02, 2025 am 06:45 AM

SCAPY 크롤러를 사용할 때 파이프 라인 파일을 작성할 수없는 이유에 대한 논의 지속적인 데이터 저장을 위해 SCAPY 크롤러를 사용할 때 파이프 라인 파일이 발생할 수 있습니다 ...

See all articles