Skip to main content
Solved

I have a Global variable in a startup python which is used in the shutdown script but the Global variable is not recognised when the python is imported as external scripts.

  • April 28, 2018
  • 10 replies
  • 112 views

Forum|alt.badge.img

Hi @takashi, I was using your method of importing an external startup & shutdown python scripts instead of typing them directly into the fme. However, I have a Global variable in the startup python which is used in the shutdown script but the Global variable is not recognised when the startup & shutdown python is imported as external scripts. eg.

import sys

 

sys.path.append('D:/Scripts')

 

import StartupPython

Best answer by david_r

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

This post is closed to further activity.
It may be an old question, an answered question, an implemented idea, or a notification-only post.
Please check post dates before relying on any information in a question or answer.
For follow-up or related questions, please post a new question or idea.
If there is a genuine update to be made, please contact us and request that the post is reopened.

10 replies

takashi
Celebrity
  • 7842 replies
  • April 28, 2018

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?


Forum|alt.badge.img
  • Author
  • 22 replies
  • April 29, 2018

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


takashi
Celebrity
  • 7842 replies
  • April 29, 2018

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)


takashi
Celebrity
  • 7842 replies
  • April 30, 2018

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 = []
        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()

david_r
Celebrity
  • 8391 replies
  • Best Answer
  • April 30, 2018

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


Forum|alt.badge.img
  • Author
  • 22 replies
  • May 2, 2018

Hi @takashi Did you get the two scripts I attached for your last question?


Forum|alt.badge.img
  • Author
  • 22 replies
  • May 2, 2018

Hi @takashi Did you get the two scripts I attached for your last question?

Sorry @takashi just found your reply. Thanks again.

 


Forum|alt.badge.img
  • Author
  • 22 replies
  • May 3, 2018

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?


takashi
Celebrity
  • 7842 replies
  • May 3, 2018

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?

 

 


  • 1 reply
  • September 18, 2018

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.