추상 기본 클래스에 메서드가 있고 하위 클래스가 해당 메서드를 구현하고 일부 선택적 키워드 인수를 추가하는 경우 기존 코드에 유형 주석을 추가하는 문제에 여러 번 부딪혔습니다. 코드가 다음과 같다고 가정합니다.
class Base:
def foo(self, x: int, **kwargs) -> None: ...
class A(Base):
def foo(self, x: int, *, frob: bool = False) -> None: ...
class B(Base):
def foo(self, x: int, *, extra: str = '') -> None: ...
Mypy는 하위 클래스 구현이 기본 클래스보다 덜 일반적이기 때문에 이를 거부합니다(임의의 키워드 인수를 허용하지 않기 때문).
kwargs
기본 클래스에서를 제거 할 수 있지만 이렇게 하면 Base
모든 인스턴스를 허용하고 다음을 통해 임의의 키워드 인수를 전달하는 함수에 문제가 발생할 수 있습니다.
def call_base(x: Base, **kwargs) -> None:
x.foo(3, **kwargs)
그러면 Base.foo가 임의의 키워드 인수를 허용하지 않기 때문에 Mypy가 불평할 것입니다.
또 다른 옵션은 파생 클래스 구현이 (unused) 를 채택하도록 하는 것이지만 kwargs
이 역시 단점이 있습니다.
- 정확도가 떨어지므로 인스턴스가 파생 클래스 중 하나에 속하는 것으로 (정적으로) 알려진 경우 mypy는 덜 유용합니다.
- 사용자가 잘못된 키워드 인수를 전달하면 이제 예외를 발생시키는 대신 자동으로 무시됩니다(이를 확인하기 위해 추가 코드가 추가되지 않는 한).
케이크를 먹고도 먹을 수 있는 방법이 있나요? 즉, 기본 클래스에서 호출될 때 추가 인수를 확인하지 않고 대신 파생 클래스에서 확인하도록 mypy에 지시합니까? 이것이 유형 모델을 위반한다고 생각할 수도 있지만(파생 클래스 메소드는 허용되는 매개변수의 범위를 좁힐 수 없음) 이미 단일 매개변수에 대해 가능합니다( Any
기본 클래스에서는 선언하지만 파생 클래스 유형에서는 구체적으로 선언).