Last active
October 9, 2019 00:51
-
-
Save rogueinkamp/593aa47a99c25d9c66a3589da2ff70d2 to your computer and use it in GitHub Desktop.
Dynamic class creation using python
This file contains hidden or 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 ABC, abstractmethod | |
| from beeprint import pp | |
| """ | |
| There may be a better more pythonic way of doing this, | |
| I am not sure. | |
| I spent a few days trying variuous methods and this was what worked the best | |
| and was the most easy to understand and implement. | |
| There are probably only a few use cases where this is needed. | |
| The program starts with an asbtract class that defines the methods each creation | |
| must use. From there I have defined an Animal class that inherits the ABC. | |
| Once I have an animal class I can dynamically create animal classes and save them for later | |
| using the "AnimalCreator" class. | |
| If a class name already exists, the factory returns an instance. | |
| """ | |
| class creation(ABC): | |
| def __init__(self, creation_name): | |
| self.creation_name = creation_name | |
| self.favorite_food = 'no favorite food found' | |
| @abstractmethod | |
| def new_favorite_food(self, new_food): | |
| raise NotImplementedError | |
| @abstractmethod | |
| def get_favorite_food(self): | |
| raise NotImplementedError | |
| @abstractmethod | |
| def say_name(self): | |
| raise NotImplementedError | |
| class Animal(creation): | |
| @classmethod | |
| def spawn(cls, name, **attributes): | |
| new_class = type(name, (cls,), attributes) | |
| globals()[name] = new_class | |
| return new_class(name) | |
| def __init__(self, name, **attributes): | |
| self.name = name | |
| for attrib, val in attributes.items(): | |
| self.attrib = val | |
| self.favorite_food = None | |
| def new_favorite_food(self, new_food): | |
| self.favorite_food = new_food | |
| print('{} tried a new food, {} and, ' | |
| 'it became an instant fav!'.format( | |
| self.friendly_name, | |
| new_food) | |
| ) | |
| def get_favorite_food(self): | |
| print(self.favorite_food) | |
| def say_name(self): | |
| print("BEHOLD! I AM: {} OF SPECIES {}!!!".format( | |
| self.friendly_name.capitalize(), | |
| self.__class__.__name__.capitalize() | |
| )) | |
| class AnimalCreator: | |
| def __init__(self): | |
| self.creations = {} | |
| def make_animal(self, creation_name, **attributes): | |
| # if we already have an class for the creation, | |
| # return an instance of the creation with the attributes | |
| if creation_name in self.creations: | |
| print('creation {} has already been created, ' | |
| 'return an new instance'.format(creation_name)) | |
| creation_inst = self.creations[creation_name] | |
| for attrib, val in attributes.items(): | |
| setattr(creation_inst, attrib, val) | |
| return creation_inst | |
| creation = Animal.spawn( | |
| creation_name, | |
| **attributes | |
| ) | |
| self.creations.update({creation_name: creation}) | |
| return creation | |
| AnimalConstructor = AnimalCreator() | |
| sparky = AnimalConstructor.make_animal('dog', friendly_name='sparky') | |
| yuna = AnimalConstructor.make_animal('dog', friendly_name='yuna') | |
| mittens = AnimalConstructor.make_animal('cat', friendly_name='mittens', favorite_food='mice') | |
| print('=' * 100) | |
| print('we have created a few new animals, here is their information:') | |
| print('=' * 100) | |
| pp(sparky) | |
| print() | |
| pp(mittens) | |
| print() | |
| pp(yuna) | |
| print() | |
| print('=' * 100) | |
| print('lets ask our new animal pets about their favorite food!:') | |
| print('=' * 100) | |
| print('sparky, what is your favorite food?') | |
| sparky.get_favorite_food() | |
| print('lets try some bones!') | |
| sparky.new_favorite_food('bones') | |
| print('sparky, what is your favorite food?') | |
| sparky.get_favorite_food() | |
| print('mittens what is your favorite food?') | |
| mittens.get_favorite_food() | |
| print('lets try some fish!') | |
| mittens.new_favorite_food('fish') | |
| print('mittens what is your favorite food?') | |
| mittens.get_favorite_food() | |
| print('=' * 100) | |
| print('what creations to we have availble for us?') | |
| print('=' * 100) | |
| print(AnimalConstructor.creations) | |
| print('=' * 100) | |
| print('lets get a new dog!!') | |
| print('=' * 100) | |
| bro = AnimalConstructor.creations['dog'] | |
| bro.friendly_name = 'bro' | |
| pp(bro) | |
| """ | |
| [evanr] ⮞⮞⮞⮞ python animal_factory.py | |
| creation dog has already been created, return an new instance | |
| ==================================================================================================== | |
| we have created a few new animals, here is their information: | |
| ==================================================================================================== | |
| instance(dog): | |
| _abc_impl: <_abc_data object at 0x7fed8bba63f0>, | |
| favorite_food: None, | |
| friendly_name: 'yuna', | |
| name: 'dog' | |
| instance(cat): | |
| _abc_impl: <_abc_data object at 0x7fed8bba6480>, | |
| favorite_food: None, | |
| friendly_name: 'mittens', | |
| name: 'cat' | |
| instance(dog): | |
| _abc_impl: <_abc_data object at 0x7fed8bba63f0>, | |
| favorite_food: None, | |
| friendly_name: 'yuna', | |
| name: 'dog' | |
| ==================================================================================================== | |
| lets ask our new animal pets about their favorite food!: | |
| ==================================================================================================== | |
| sparky, what is your favorite food? | |
| None | |
| lets try some bones! | |
| yuna tried a new food, bones and, it became an instant fav! | |
| sparky, what is your favorite food? | |
| bones | |
| mittens what is your favorite food? | |
| None | |
| lets try some fish! | |
| mittens tried a new food, fish and, it became an instant fav! | |
| mittens what is your favorite food? | |
| fish | |
| ==================================================================================================== | |
| what creations to we have availble for us? | |
| ==================================================================================================== | |
| {'dog': <abc.dog object at 0x7fed8bb84e50>, 'cat': <abc.cat object at 0x7fed8bb8a250>} | |
| ==================================================================================================== | |
| lets get a new dog!! | |
| ==================================================================================================== | |
| instance(dog): | |
| _abc_impl: <_abc_data object at 0x7fed8bba63f0>, | |
| favorite_food: 'bones', | |
| friendly_name: 'bro', | |
| name: 'dog' | |
| """ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment