Python: TypeVar covariance contravariance invariance

 

contra-variance

复制代码
from typing import Callable


class Food:
    ...


class Meat(Food):
    ...


class Animal:
    def eat(self, food: Food):
        ...


class Dog(Animal):
    def eat(self, food: Food):
        ...

    def dog(self):
        print('Dog', self)


a: Animal = Animal()
d: Dog = Dog()


def animal_run(animal: Animal) -> None:  # Callable[[Animal], None]
    print('An animal is running!')


def dog_run(dog: Dog) -> None:  # Callable[[Dog], None]
    print('A dog is running!')
    dog.dog()


animal_run(a)
dog_run(d)

# Dog <: Animal
# Callable[[Animal], None] <: Callable[[Dog], None]  contra-variance


def make_dog_run(dog: Dog, run_function: Callable[[Dog], None]) -> None:
    run_function(dog)


lassie: Dog = Dog()
make_dog_run(dog=lassie, run_function=animal_run)
make_dog_run(dog=lassie, run_function=dog_run)
复制代码

 

https://dev.to/daniel1in/python-type-hint-contravariant-covariant-invariant-15lj

 

 

 

 

 

复制代码
from abc import ABCMeta, abstractmethod
from typing import TypeVar, Generic


class Base:
    def foo(self):
        print('foo')


class Derived(Base):
    def bar(self):
        print('bar')


T_contra = TypeVar('T_contra', bound=Base, covariant=True, contravariant=False)


class Sink(Generic[T_contra]):
    @abstractmethod
    def consume(self, value: T_contra):
        ...


class SinkBase(Sink[Base]):
    def consume(self, value: Base):
        value.foo()


class SinkDerived(Sink[Derived]):
    def consume(self, value: Derived):
        value.bar()

    def other_func(self):
        ...


base = Base()
derived = Derived()

sink_base: Sink[Base] = SinkDerived()
sink_derived: Sink[Derived] = SinkBase()


class Source(Generic[T_contra]):
    @abstractmethod
    def generate(self) -> T_contra:
        ...


class SourceBase(Source[Base]):
    def generate(self) -> Derived:
        return Derived()


class SourceDerived(Source[Derived]):
    def generate(self) -> Derived:
        return Derived()


source: Source[Base] = SourceDerived()
source.generate()

source_derived: Source[Derived] = SourceBase()
source_derived.generate()
复制代码

 

 

 

 

 

https://blog.daftcode.pl/covariance-contravariance-and-invariance-the-ultimate-python-guide-8fabc0c24278

posted @   ascertain  阅读(43)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示