Though the question is very specific, I’d also really appreciate general advice and other approaches that would make my question moot. I’m building a collection of AI programs, and many of the functions and classes need to deal with a lot of different states and actions that cause transitions between states, so I need a way to represent states and actions. Please note that I’m not building a simple state machine, but rather a number of different programs (agents) that all take states and return actions as a way of interacting with an environment.
I could use strings, but that’s messy if a particular algorithm needs to associate additional information with a state or action, and comparing strings over and over again in long-running programs is wasted overhead. The same sorts of problems arise with other kinds of constants. So my initial idea is to use nested classes, like so:
class DerivedAgent(Agent):
class StateA(State): pass
class StateB(State): pass
...
def do_something(state):
if state is self.StateA:
...
This works fairly well, but if there are a number of states and actions, it can take up a lot of space to declare them all, and all of the pass statements are annoying. I’d like to be able to do something like…
class DerivedAgent(Agent):
states("StateA", "StateB", "StateC", ...)
But I don’t see a way to have the states method add the newly-created types to the DerivedAgent class. I think I might be able to do it with the inspect module, but that feels like it’s going too far for a small convenience. Is using types like this a bad idea? Is there a much more elegant approach? Code outside of the agent classes will need to be able to access the states and actions, and putting states into the module namespace isn’t a good option because a given module might have several agents in it.
You could use meta classes so that you would end up with code like:
for example:
then, just rewrite your
Agentclass so that it has the lineIf you don’t want to change the
Agentclass, you can just include the approriate declaration of metaclass in each subclass of it that you create.