>  기사  >  백엔드 개발  >  오리 타이핑과 유형 힌트의 만남: Python에서 프로토콜 사용

오리 타이핑과 유형 힌트의 만남: Python에서 프로토콜 사용

WBOY
WBOY원래의
2024-07-31 10:40:341086검색

Duck Typing Meets Type Hints: Using Protocols in Python

Python의 동적인 특성과 덕 타이핑 지원은 유연성으로 인해 오랫동안 칭찬을 받아 왔습니다. 그러나 코드베이스가 더 커지고 복잡해짐에 따라 정적 유형 검사의 이점이 점점 더 분명해집니다. 하지만 덕 타이핑의 유연성과 정적 유형 검사의 안전성을 어떻게 조화시킬 수 있을까요? Python의 프로토콜 클래스를 입력하세요.

이 튜토리얼에서 배울 내용은 다음과 같습니다.

  1. 오리 타이핑(Duck Typing)이 무엇이며 Python에서 어떻게 지원되는지
  2. 덕타이핑의 장점과 단점
  3. ABC(추상 기본 클래스)가 입력 문제를 해결하는 방법
  4. 프로토콜을 사용하여 두 가지 장점을 모두 활용하는 방법: 정적 유형 검사를 통한 덕 타이핑 유연성

오리 타이핑 이해

오리 타이핑은 개체의 유형이나 클래스가 개체가 정의하는 메서드보다 덜 중요한 프로그래밍 개념입니다. '오리처럼 보이고, 오리처럼 헤엄치고, 오리처럼 꽥꽥거린다면 아마도 오리일 것이다'라는 생각에서 출발한 것입니다.

Python에서는 덕 타이핑이 완벽하게 지원됩니다. 예:

class Duck:
    def quack(self):
        print("Quack!")

class Person:
    def quack(self):
        print("I'm imitating a duck!")

def make_it_quack(thing):  # Note: No type hint here
    thing.quack()

duck = Duck()
person = Person()

make_it_quack(duck)    # Output: Quack!
make_it_quack(person)  # Output: I'm imitating a duck!

이 예에서 make_it_quack은 사물의 유형에 관심이 없습니다. 그 물건에 돌팔이 방법이 있는지에만 관심이 있습니다. thing 매개변수에 대한 유형 힌트가 없다는 점에 유의하세요. 이는 duck 유형의 코드에서 일반적이지만 더 큰 코드베이스에서는 문제를 일으킬 수 있습니다.

오리 타이핑의 장점과 단점

덕 타이핑은 여러 가지 장점을 제공합니다.

  1. 유연성: 특정 유형에 얽매이지 않는 보다 유연한 코드를 허용합니다.
  2. 더 쉬워진 코드 재사용: 수정 없이 기존 클래스를 새로운 컨텍스트에서 사용할 수 있습니다.
  3. 행동 강조: 개체가 무엇인지보다는 개체가 무엇을 할 수 있는지에 중점을 둡니다.

그러나 몇 가지 단점도 있습니다.

  1. 명확성 부족: 객체가 어떤 메소드를 구현해야 하는지 불분명할 수 있습니다.
  2. 런타임 오류: 유형 관련 오류는 런타임에만 포착됩니다.
  3. 적은 IDE 지원: IDE는 정확한 자동 완성 및 오류 검사를 제공하는 데 어려움을 겪습니다.

ABC 솔루션

이러한 문제를 해결하는 한 가지 접근 방식은 ABC(추상 기본 클래스)를 사용하는 것입니다. 예는 다음과 같습니다.

from abc import ABC, abstractmethod

class Quacker(ABC):
    @abstractmethod
    def quack(self):
        pass

class Duck(Quacker):
    def quack(self):
        print("Quack!")

class Person(Quacker):
    def quack(self):
        print("I'm imitating a duck!")

def make_it_quack(thing: Quacker):
    thing.quack()

duck = Duck()
person = Person()

make_it_quack(duck)
make_it_quack(person)

이 접근 방식은 더 나은 유형 검사와 더 명확한 인터페이스를 제공하지만 다음과 같은 단점도 있습니다.

  1. 상속이 필요하며 이는 경직된 계층 구조로 이어질 수 있습니다.
  2. 수정이 ​​불가능한 기존 클래스에서는 작동하지 않습니다.
  3. 이는 Python의 "오리 타이핑" 철학에 위배됩니다.

프로토콜: 양쪽 세계의 최고

Python 3.8에는 상속 없이 인터페이스를 정의할 수 있는 프로토콜 클래스가 도입되었습니다. 사용 방법은 다음과 같습니다.

from typing import Protocol

class Quacker(Protocol):
    def quack(self):...

class Duck:
    def quack(self):
        print("Quack!")

class Person:
    def quack(self):
        print("I'm imitating a duck!")

def make_it_quack(thing: Quacker):
    thing.quack()

duck = Duck()
person = Person()

make_it_quack(duck)
make_it_quack(person)

이를 분석해 보겠습니다.

  1. 우리는 우리가 기대하는 인터페이스를 지정하는 Quacker 프로토콜을 정의합니다.
  2. Duck 및 Person 클래스는 어떤 것에서도 상속할 필요가 없습니다.
  3. make_it_quack에 유형 힌트를 사용하여 Quacker가 예상됨을 지정할 수 있습니다.

이러한 접근 방식은 다음과 같은 몇 가지 이점을 제공합니다.

  1. 정적 유형 검사: IDE 및 유형 검사기는 런타임 전에 오류를 포착할 수 있습니다.
  2. 상속이 필요하지 않습니다. 기존 클래스는 올바른 메소드가 있는 한 작동합니다.
  3. 명확한 인터페이스: 프로토콜은 어떤 메서드가 예상되는지 명확하게 정의합니다.

다음은 도메인 클래스(원, 직사각형)를 평면으로 유지하면서 프로토콜이 필요한 만큼 복잡할 수 있는 방법(모양)을 보여주는 더 복잡한 예입니다.

from typing import Protocol, List

class Drawable(Protocol):
    def draw(self): ...

class Resizable(Protocol):
    def resize(self, factor: float): ...

class Shape(Drawable, Resizable, Protocol):
    pass

def process_shapes(shapes: List[Shape]):
    for shape in shapes:
        shape.draw()
        shape.resize(2.0)

# Example usage
class Circle:
    def draw(self):
        print("Drawing a circle")

    def resize(self, factor: float):
        print(f"Resizing circle by factor {factor}")

class Rectangle:
    def draw(self):
        print("Drawing a rectangle")

    def resize(self, factor: float):
        print(f"Resizing rectangle by factor {factor}")

# This works with any class that has draw and resize methods,
# regardless of its actual type or inheritance
shapes: List[Shape] = [Circle(), Rectangle()]
process_shapes(shapes)

이 예에서 Circle 및 Rectangle은 Shape 또는 다른 클래스에서 상속되지 않습니다. 그들은 단순히 필요한 메소드(그리기 및 크기 조정)를 구현합니다. process_shapes 함수는 Shape 프로토콜 덕분에 이러한 메소드를 가진 모든 객체와 함께 작동할 수 있습니다.

요약

Python의 프로토콜은 덕 유형의 코드에 정적 유형을 적용하는 강력한 방법을 제공합니다. 이를 통해 상속을 요구하지 않고 유형 시스템에서 인터페이스를 지정할 수 있으며 덕 타이핑의 유연성을 유지하면서 정적 유형 검사의 이점을 추가할 수 있습니다.

프로토콜을 사용하면 다음이 가능합니다.

  1. 코드에 대한 명확한 인터페이스 정의
  2. 더 나은 IDE(정적 유형 검사), 지원 및 오류 조기 발견
  3. 덕타이핑의 유연성 유지
  4. 수정할 수 없는 클래스에 대한 유형 검사를 활용하세요.

Python의 프로토콜 및 유형 힌트에 대해 자세히 알아보려면 타이핑 모듈에 대한 공식 Python 문서를 확인하거나 mypy와 같은 고급 정적 유형 검사 도구를 살펴보세요.

즐거운 코딩을 즐기시고, 여러분의 오리가 항상 유형 안전을 지키길 바랍니다!

여기에서 내 뉴스레터를 포함한 더 많은 콘텐츠를 찾을 수 있습니다

위 내용은 오리 타이핑과 유형 힌트의 만남: Python에서 프로토콜 사용의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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