import random
from typing import Type

class Pet:
    def __init__(self, name: str) -> None: = name

    def speak(self) -> None:
        raise NotImplementedError

    def __str__(self) -> str:
        raise NotImplementedError

class Dog(Pet):
    def speak(self) -> None:

    def __str__(self) -> str:
        return f"Dog<{}>"

class Cat(Pet):
    def speak(self) -> None:

    def __str__(self) -> str:
        return f"Cat<{}>"

class PetShop:

    """A pet shop"""

    def __init__(self, animal_factory: Type[Pet]) -> None:
        """pet_factory is our abstract factory.  We can set it at will."""

        self.pet_factory = animal_factory

    def buy_pet(self, name: str) -> Pet:
        """Creates and shows a pet using the abstract factory"""

        pet = self.pet_factory(name)
        print(f"Here is your lovely {pet}")
        return pet

# Additional factories:

# Create a random animal
def random_animal(name: str) -> Pet:
    """Let's be dynamic!"""
    return random.choice([Dog, Cat])(name)

# Show pets with various factories
def main() -> None:
    # A Shop that sells only cats
    >>> cat_shop = PetShop(Cat)
    >>> pet = cat_shop.buy_pet("Lucy")
    Here is your lovely Cat<Lucy>
    >>> pet.speak()

    # A shop that sells random animals
    >>> shop = PetShop(random_animal)
    >>> for name in ["Max", "Jack", "Buddy"]:
    ...    pet = shop.buy_pet(name)
    ...    pet.speak()
    ...    print("=" * 20)
    Here is your lovely Cat<Max>
    Here is your lovely Dog<Jack>
    Here is your lovely Dog<Buddy>

if __name__ == "__main__":
    random.seed(1234)  # for deterministic doctest outputs
    import doctest


原文地址:python-patterns/ at master · faif/python-patterns · GitHub