python interface with ABC, Protocol, goose typing

x·2024년 4월 19일
0

python

목록 보기
4/4

ABC를 사용한 인터페이스와 인터페이스의 모든 속성을 구현하지 않은 구현체

from abc import ABC, abstractmethod

class FlyerInterface(ABC):
    @abstractmethod
    def fly(self) -> None:
        pass
    
    @abstractmethod
    def nothing(self) -> None:
        pass

class Bird(FlyerInterface):
    def fly(self) -> None:
        print("이 새는 날아다닙니다.")

bird = Bird()

def lift_off(entity: Flyer) -> None:
    entity.fly()
    
lift_off(bird)

ABC(Abstract Base Classes)를 사용해서 인터페이스를 정의했다. 구현체에서 nothing()을 구현하고 있지 않아 에러가 발생한다.

ERROR!
Traceback (most recent call last):
  File "<main.py>", line 36, in <module>
TypeError: Can't instantiate abstract class Bird with abstract method nothing

ABC를 사용한 인터페이스와 인터페이스의 모든 속성을 구현한 구현체

from abc import ABC, abstractmethod

class FlyerInterface(ABC):
    @abstractmethod
    def fly(self) -> None:
        pass

class Bird(FlyerInterface):
    def fly(self) -> None:
        print("이 새는 날아다닙니다.")
        
    def walk(self) -> None:
        print("이 새는 걸어다닙니다.")


bird = Bird()

def lift_off(entity: FlyerInterface) -> None:
    entity.fly()

def walk(entity: FlyerInterface) -> None:
    entity.walk()
    
print(f"isinstance : {isinstance(bird, FlyerInterface)}")
print(f"issubclass : {issubclass(Bird, FlyerInterface)}")

lift_off(bird)
walk(bird)

Bird 구현체가 interface의 메서드를 모두 구현했으므로 FlyerInterface의 instance이면서 subclass다.

isinstance : True
issubclass : True
이 새는 날아다닙니다.

Protocol을 사용한 인터페이스와 인터페이스의 일부 속성만 구현한 구현체

from typing import Protocol, runtime_checkable

@runtime_checkable
class Flyer(Protocol):
    def fly(self) -> None:
        print('flyer')
        
    def nothing(self) -> None:
        pass

class Bird:
    def fly(self) -> None:
        print("이 새는 날아다닙니다.")

bird = Bird()

def lift_off(entity: Flyer) -> None:
    entity.fly()

print(f"isinstance : {isinstance(bird, Flyer)}")
print(f"issubclass : {issubclass(Bird, Flyer)}")

lift_off(bird)

Bird 클래스에 nothing()은 구현되어 있지 않고 fly만 구현되어 있어도 실행이 된다.

isinstance : False
issubclass : False
이 새는 날아다닙니다.

Protocol을 사용한 인터페이스와 인터페이스의 모든 속성을 구현하지 않은 구현체

from typing import Protocol, runtime_checkable

@runtime_checkable
class Flyer(Protocol):
    def fly(self) -> None:
        print('flyer')
        
    def nothing(self) -> None:
        pass

class Whale:
    def swim(self) -> None:
        print("이 고래는 수영합니다.")

whale = Whale()

def lift_off(entity: Flyer) -> None:
    entity.fly()
    
print(f"isinstance : {isinstance(whale, Flyer)}")
print(f"issubclass : {issubclass(Whale, Flyer)}")
    
lift_off(whale)

Whale 클래스에는 fly 메서드가 구현되어 있지 않다.
whale은 Flyer의 instance도 subclass도 아니다.
fly가 없다는 에러가 발생함.

isinstance : False
issubclass : False
ERROR!
Traceback (most recent call last):
  File "<main.py>", line 23, in <module>
  File "<main.py>", line 18, in lift_off
AttributeError: 'Whale' object has no attribute 'fly'

Protocol을 사용한 인터페이스와 인터페이스의 모든 속성을 구현한 구현체

from typing import Protocol, runtime_checkable

@runtime_checkable
class Flyer(Protocol):
    def fly(self) -> None:
        print('flyer')

class Bird:
    def fly(self) -> None:
        print("이 새는 날아다닙니다.")
        
    def walk(self) -> None:
        print("이 새는 걸어다닙니다.")

bird = Bird()

def lift_off(entity: Flyer) -> None:
    entity.fly()

def walk(entity: Flyer) -> None:
    entity.walk()
    
print(f"isinstance : {isinstance(bird, Flyer)}")
print(f"issubclass : {issubclass(Bird, Flyer)}")

lift_off(bird)
walk(bird)
isinstance : True
issubclass : True
이 새는 날아다닙니다.
이 새는 걸어다닙니다.

ABC를 사용한 인터페이스는 구현체가 인터페이스의 모든 속성과 메서드를 구현하도록 강제한다.
Protocol을 사용한 인터페이스는 구현체가 인터페이스의 일부 속성과 메서드만 구현해도 되게 한다.

0개의 댓글