Last active
September 15, 2022 07:17
-
-
Save olidroide/48a57ba05d9446b8bb85b9bbd4019edd to your computer and use it in GitHub Desktop.
Python Generic generation from typevar Python 3.9.5 tested
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from abc import abstractmethod | |
from typing import TypeVar, Generic, get_args, Type, List | |
class Fruit: | |
@abstractmethod | |
def fruit_name(self) -> str: | |
raise NotImplementedError | |
class Apple(Fruit): | |
def fruit_name(self) -> str: | |
return self.__class__.__name__ | |
class Leaf: | |
@staticmethod | |
def leaf_color(): | |
return "green" | |
_FruitType = TypeVar("_FruitType", bound=Fruit) | |
class Tree(Generic[_FruitType], Leaf): | |
_type_generic: Type[_FruitType] | |
_fruits: List[_FruitType] | |
def __init__(self) -> None: | |
super().__init__() | |
self._type_generic = get_args(self.__orig_bases__[0])[0] # magic here idea from https://stackoverflow.com/a/71720366/481637 | |
self._fruits = list() | |
def generate_fruit(self): | |
self._fruits.append(self._type_generic()) | |
def take_fruit(self) -> _FruitType: | |
if not self._fruits: | |
raise NotImplementedError | |
return self._fruits.pop() | |
@property | |
def count_fruits(self) -> int: | |
return len(self._fruits) | |
def tree_name(self): | |
return self.__class__.__name__ | |
class Fuji(Tree[Apple]): | |
pass | |
class Person: | |
@staticmethod | |
def eat(food: Fruit): | |
print(f"eating {food.fruit_name()} ñam") | |
food = None | |
fuji_apple_tree = Fuji() | |
print(f"Created {fuji_apple_tree.tree_name()} Tree with {fuji_apple_tree.leaf_color()} color") | |
# Created Fuji Tree with green color | |
fuji_apple_tree.generate_fruit() | |
print(f"{fuji_apple_tree.tree_name()} Tree with {fuji_apple_tree.count_fruits} fruits generated") | |
# Fuji Tree with 1 fruits generated | |
fruit = fuji_apple_tree.take_fruit() | |
person = Person() | |
person.eat(fruit) | |
# eating Apple ñam |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from abc import abstractmethod | |
from typing import Type, List | |
class Fruit: | |
@abstractmethod | |
def fruit_name(self) -> str: | |
raise NotImplementedError | |
class Apple(Fruit): | |
def fruit_name(self) -> str: | |
return self.__class__.__name__ | |
class Leaf: | |
@staticmethod | |
def leaf_color(): | |
return "green" | |
class Tree(Leaf): | |
_fruits: List[Fruit] | |
@property | |
@abstractmethod | |
def kind_of_fruit(self) -> Type[Fruit]: | |
raise NotImplementedError | |
def __init__(self) -> None: | |
super().__init__() | |
self._fruits = list() | |
def generate_fruit(self): | |
self._fruits.append(self.kind_of_fruit()) | |
def take_fruit(self) -> Fruit: | |
if not self._fruits: | |
raise IndexError | |
return self._fruits.pop() | |
@property | |
def count_fruits(self) -> int: | |
return len(self._fruits) | |
def tree_name(self): | |
return self.__class__.__name__ | |
class Fuji(Tree): | |
@property | |
def kind_of_fruit(self) -> Type[Apple]: | |
return Apple | |
class Person: | |
@staticmethod | |
def eat(food: Fruit): | |
print(f"eating {food.fruit_name()} ñam") | |
food = None | |
fuji_apple_tree = Fuji() | |
print(f"Created {fuji_apple_tree.tree_name()} Tree with {fuji_apple_tree.leaf_color()} color") | |
fuji_apple_tree.generate_fruit() | |
print(f"{fuji_apple_tree.tree_name()} Tree with {fuji_apple_tree.count_fruits} fruits generated") | |
fruit = fuji_apple_tree.take_fruit() | |
fruit.fruit_name() | |
person = Person() | |
person.eat(fruit) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment