Caching data between script runs?

This is a purely hypothetical question, but as I can’t answer it myself it must mean that my Ignition knowledge is lacking.

Given a script that runs repetively, such as a timer script or a change valve script, is there a mechanism for caching data within the jython scripting space for a particular instance of the script? And can this be done without hiding the data in a tag somewhere?

I’m doing a mental exercise of lazy loading of resources and wondering if it can be done. And example of this would be constructing an array of paths that would be fed into a tag read function - and not doing it on the fly every time the script runs. (and yes I know that is potentially a micro-optimization - unless the number of instances starts to challenge the memory limitations of the GW)

I think this is about as close as you can get.

Every variable you create at the outermost/topmost level persists until the script is restarted. Create a named dictionary outside of any function and any keys you set on it will persist. Also valuable for constants and one-time generated pseudo-constants like lists of tag paths.

If you need persistence that survives script restarts, follow the link @lrose posted. Many caching activities do not need that kind of persistence.

What defines restart? That's a very vague concept. However as most of things I'm talking about are GW based scripts (timer and tag change) that nominally this would be a GW restart (or a script edit)

And no, I'm not looking for the persistence that @lrose is talking about, but it is interesting to know that exists.

Not vague at all. Just a save a project in the designer and its gateway scripts will restart. (And if an inheritable project, any dependent projects' scripts will restart.) Look at your gateway log while you save.

Each project in the gateway has a jython script environment that includes all of the relevent script modules. After a restart, the first reference to any name in a script module causes that script module to be imported, establishing its namespace. The import happens under an interpreter lock to ensure it completes before any referenced name is actually used. That means top-level variables defined anywhere in the script are present before any function defined in the module can run. The only exception would be if the top level of the script itself calls one of its own functions.

Similarly, if a function called in a script module calls another script's function, and happens to be the first reference, that other script will be imported at that point.