Storing the state of script between steps

Steven D'Aprano steve+comp.lang.python at pearwood.info
Fri Feb 21 22:42:35 EST 2014


On Fri, 21 Feb 2014 12:59:11 -0800, Denis Usanov wrote:

> I mostly develop on Python some automation scripts such as deployment
> (it's not about fabric and may be not ssh at all), testing something,
> etc. In this terms I have such abstraction as "step".
> 
> Some code:
> 
> class IStep(object):
>     def run():
>         raise NotImplementedError()
> 
> And the certain steps:
> 
> class DeployStep: ...
> class ValidateUSBFlash: ...
> class SwitchVersionS: ...
> 
> Where I implement run method.

Why are these classes? Unless you have multiple instances, or are using 
inheritance, the use of classes is a Java-ism and a waste of time.

http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html

Since I see no reason to (say) have multiple ValidateUSBFlash instances, 
with different state, at the same time, and no reason to have (say) 
SwitchVersionS inherit from (say) DeployStep, I suggest a better approach 
is to use functions. No more ValidateUSBFlash.run method calls, just call 
function validate_usb_flash.

> Then I use some "builder" class which can add steps to internal list and
> has a method "start" running all step one by one.

That becomes:

steps = [deploy_step, validate_usb_flash, switch_version_s, ...]

for step in steps:
    step()


> And I like this. It's loosely coupled system. It works fine in simple
> cases. But sometimes some steps have to use the results from previous
> steps. And now I have problems. Before now I had internal dict in
> "builder" and named it as "world" and passed it to each run() methods of
> steps. It worked but I disliked this.
> 
> How would you solve this problem and how would you do it? I understant
> that it's more architecture specific question, not a python one.


I'd avoid over-generalisation, and just write a script. Let each step 
function take whatever arguments it needs, and return whatever arguments 
it requires, then write it like this:

deploy_step()
result = validate_usb_flash()
if result == 1:
    validate_other_usb_flash()
else:
    validate_something_else(result)

I mean, how many steps do you have? Twenty? A hundred? It's not that hard 
to maintain a 100 or 200 line script. And are you likely to have so many 
different versions of it that you need extra abstraction layers?

Of course, I might be misinterpreting your post. Perhaps you do have so 
many steps, and so many different types of deployment, that you do need a 
more heavily abstracted system. In that case, I think you need to 
describe your system in more detail to get any useful answers. But don't 
over-generalise, and don't become an Architecture Astronaut :-)


-- 
Steven



More information about the Python-list mailing list