Skip to content

Instantly share code, notes, and snippets.

@rogueinkamp
Last active October 9, 2019 00:51
Show Gist options
  • Select an option

  • Save rogueinkamp/593aa47a99c25d9c66a3589da2ff70d2 to your computer and use it in GitHub Desktop.

Select an option

Save rogueinkamp/593aa47a99c25d9c66a3589da2ff70d2 to your computer and use it in GitHub Desktop.
Dynamic class creation using python
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