added cafeteria example
This commit is contained in:
82
15-more-types/cafeteria.py
Normal file
82
15-more-types/cafeteria.py
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
from typing import TypeVar, Generic
|
||||||
|
|
||||||
|
|
||||||
|
class Beverage:
|
||||||
|
"""Any beverage"""
|
||||||
|
|
||||||
|
|
||||||
|
class Juice(Beverage):
|
||||||
|
"""Any fruit juice"""
|
||||||
|
|
||||||
|
|
||||||
|
class OrangeJuice(Juice):
|
||||||
|
"""Delicious juice from Brazilian oranges"""
|
||||||
|
|
||||||
|
|
||||||
|
BeverageT = TypeVar('BeverageT', covariant=True)
|
||||||
|
|
||||||
|
|
||||||
|
class BeverageDispenser(Generic[BeverageT]):
|
||||||
|
def __init__(self, beverage: BeverageT) -> None:
|
||||||
|
self.beverage = beverage
|
||||||
|
|
||||||
|
def dispense(self) -> BeverageT:
|
||||||
|
return self.beverage
|
||||||
|
|
||||||
|
|
||||||
|
class Garbage:
|
||||||
|
"""Any garbage."""
|
||||||
|
|
||||||
|
|
||||||
|
class Biodegradable(Garbage):
|
||||||
|
"""Biodegradable garbage."""
|
||||||
|
|
||||||
|
|
||||||
|
class Compostable(Biodegradable):
|
||||||
|
"""Compostable garbage."""
|
||||||
|
|
||||||
|
|
||||||
|
GarbageT = TypeVar('GarbageT', contravariant=True)
|
||||||
|
|
||||||
|
|
||||||
|
class TrashCan(Generic[GarbageT]):
|
||||||
|
def put(self, trash) -> None:
|
||||||
|
"""Store trash until dumped..."""
|
||||||
|
|
||||||
|
|
||||||
|
class Cafeteria:
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
dispenser: BeverageDispenser[Juice],
|
||||||
|
trash_can: TrashCan[Biodegradable]
|
||||||
|
):
|
||||||
|
"""Initialize..."""
|
||||||
|
|
||||||
|
|
||||||
|
beverage_dispenser = BeverageDispenser(Beverage())
|
||||||
|
juice_dispenser = BeverageDispenser(Juice())
|
||||||
|
orange_juice_dispenser = BeverageDispenser(OrangeJuice())
|
||||||
|
|
||||||
|
trash_can: TrashCan[Garbage] = TrashCan()
|
||||||
|
bio_can: TrashCan[Biodegradable] = TrashCan()
|
||||||
|
compost_can: TrashCan[Compostable] = TrashCan()
|
||||||
|
|
||||||
|
arnold_hall = Cafeteria(juice_dispenser, bio_can)
|
||||||
|
|
||||||
|
######################## covariance on 1st argument
|
||||||
|
arnold_hall = Cafeteria(orange_juice_dispenser, trash_can)
|
||||||
|
|
||||||
|
## Argument 1 to "Cafeteria" has
|
||||||
|
## incompatible type "BeverageDispenser[Beverage]"
|
||||||
|
## expected "BeverageDispenser[Juice]"
|
||||||
|
# arnold_hall = Cafeteria(beverage_dispenser, trash_can)
|
||||||
|
|
||||||
|
|
||||||
|
######################## contravariance on 2nd argument
|
||||||
|
|
||||||
|
## Argument 2 to "Cafeteria" has
|
||||||
|
## incompatible type "TrashCan[Compostable]"
|
||||||
|
## expected "TrashCan[Biodegradable]"
|
||||||
|
# arnold_hall = Cafeteria(juice_dispenser, compost_can)
|
||||||
|
|
||||||
|
arnold_hall = Cafeteria(juice_dispenser, trash_can)
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
from typing import TypeVar, Generic
|
|
||||||
|
|
||||||
|
|
||||||
class Beverage:
|
|
||||||
"""Any beverage"""
|
|
||||||
|
|
||||||
|
|
||||||
class Juice(Beverage):
|
|
||||||
"""Any fruit juice"""
|
|
||||||
|
|
||||||
|
|
||||||
class OrangeJuice(Juice):
|
|
||||||
"""Delicious juice Brazilian oranges"""
|
|
||||||
|
|
||||||
|
|
||||||
class Coak(Beverage):
|
|
||||||
"""Secret formula with lots of sugar"""
|
|
||||||
|
|
||||||
|
|
||||||
BeverageT = TypeVar('BeverageT', bound=Beverage)
|
|
||||||
JuiceT = TypeVar('JuiceT', bound=Juice)
|
|
||||||
|
|
||||||
|
|
||||||
class BeverageDispenser(Generic[BeverageT]):
|
|
||||||
|
|
||||||
beverage: BeverageT
|
|
||||||
|
|
||||||
def __init__(self, beverage: BeverageT) -> None:
|
|
||||||
self.beverage = beverage
|
|
||||||
|
|
||||||
def dispense(self) -> BeverageT:
|
|
||||||
return self.beverage
|
|
||||||
|
|
||||||
|
|
||||||
class JuiceDispenser(BeverageDispenser[JuiceT]):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class Cafeteria:
|
|
||||||
def __init__(self, dispenser: BeverageDispenser[JuiceT]):
|
|
||||||
self.dispenser = dispenser
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
from cafeteria import (
|
|
||||||
Cafeteria,
|
|
||||||
BeverageDispenser,
|
|
||||||
JuiceDispenser,
|
|
||||||
Juice,
|
|
||||||
OrangeJuice,
|
|
||||||
Coak,
|
|
||||||
)
|
|
||||||
|
|
||||||
orange = OrangeJuice()
|
|
||||||
|
|
||||||
orange_dispenser: JuiceDispenser[OrangeJuice] = JuiceDispenser(orange)
|
|
||||||
|
|
||||||
juice: Juice = orange_dispenser.dispense()
|
|
||||||
|
|
||||||
soda = Coak()
|
|
||||||
|
|
||||||
## Value of type variable "JuiceT" of "JuiceDispenser" cannot be "Coak"
|
|
||||||
# soda_dispenser = JuiceDispenser(soda)
|
|
||||||
|
|
||||||
soda_dispenser = BeverageDispenser(soda)
|
|
||||||
|
|
||||||
arnold_hall = Cafeteria(soda_dispenser)
|
|
||||||
@@ -10,10 +10,6 @@ class Pet:
|
|||||||
"""Domestic animal kept for companionship."""
|
"""Domestic animal kept for companionship."""
|
||||||
|
|
||||||
|
|
||||||
class Dog(Pet):
|
|
||||||
"""Canis familiaris"""
|
|
||||||
|
|
||||||
|
|
||||||
class Cat(Pet):
|
class Cat(Pet):
|
||||||
"""Felis catus"""
|
"""Felis catus"""
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user