Hi @johnm, I think global variables defined in an external script file can also be used in Startup/Shutdown script in a workspace. Can you show us some code snippets to clarify the followings?
- How did you define the global variable in "StartupPython.py"?
- How did you use the variable in the Startup and/or Shutdown script in the workspace?
Hi @takashi I have attached the startup and shutdown scripts which would have a .py extension if imported in the Workspace. They originally came from your code when I was trying to grab all the Errors from the log file when the Workspace is running. They work well when they are copied in as text but when they are imported as .py files, the shutdown script fails to recognise the global 'errors' variable. Thanks again for your help on this. Regards, John
startuppython.txtshutdownpython.txt
Each script file will be interpreted independently, Python interpreter cannot recognize where the variable "errors" come from, unless you import it explicitly. You have to import "startuppython" into "shutdownpython.py". For example, assuming both "startuppython.py" and "shutdownpython.py" are saved in the same folder,
# shutdownpython.py
import startuppython
print(startuppython.errors)
or
# shutdownpython.py
from startuppython import errors
print(errors)
Each script file will be interpreted independently, Python interpreter cannot recognize where the variable "errors" come from, unless you import it explicitly. You have to import "startuppython" into "shutdownpython.py". For example, assuming both "startuppython.py" and "shutdownpython.py" are saved in the same folder,
# shutdownpython.py
import startuppython
print(startuppython.errors)
or
# shutdownpython.py
from startuppython import errors
print(errors)
You can also define both startup process and shutdown process in a single script. e.g.
# External Script
# C:/Scripts/errorcollector.py
import fme, fmeobjects
class FMEErrorCollector(object):
def __init__(self):
self.errors = o]
def errorCollector(severity, message):
if severity in (fmeobjects.FME_ERROR, fmeobjects.FME_FATAL):
self.errors.append(message)
self.callback = errorCollector
fmeobjects.FMELogFile().setCallBack(self.callback)
def shutdown(self):
try:
# Do something.
print('shutdown: try') # test
except:
# Do something.
print('shutdown: except') # test
finally:
if 0 < len(self.errors):
# Do something.
print(self.errors) # test
# Workspace: Startup Python Script
import sys
sys.path.append('C:/Scripts')
from errorcollector import FMEErrorCollector
errorCollector = FMEErrorCollector()
# Workspace: Shutdown Python Script
errorCollector.shutdown()
In addition to the excellent replies from Takashi, I'll just add that this question touches on what's commonly called scope resolution in programming languages.
This is a pretty good starting point for learning more about how Python handles scopes and namespaces, and it explains why the answers from Takashi work: http://sebastianraschka.com/Articles/2014_python_scope_and_namespaces.html
Hi @takashi Did you get the two scripts I attached for your last question?
Hi @takashi Did you get the two scripts I attached for your last question?
Sorry @takashi just found your reply. Thanks again.
Hi @takashi The import of the startup script into the shutdown script did not work for me. Maybe I will have to write the data from the errors variable to a text file in the startup script?
Hi @takashi The import of the startup script into the shutdown script did not work for me. Maybe I will have to write the data from the errors variable to a text file in the startup script?
How did you write the Startup and Shutdown scripts in the workspace to execute the external scripts?
You can achieve something like this using the
reload
global function to re-execute your main script's code. You will need to write a wrapper script that imports your main script, asks it for the variable it wants to cache, caches a copy of that within the wrapper script's module scope, and then when you want (when you hit ENTER on stdin or whatever), it calls
reload(yourscriptmodule)
but this time passes it the cached object such that yourscript can bypass the expensive computation.