Create global variables in pythonista_startup
Hi guys, I can't create global variables using pythonista_startup script (that is every time I start Pythonista). Maybe it is an easy thing for you...maybe I can't remember the solution...
pythonista_startup.pyscript for test on global variables is:
def test_global(): global x x = 10 print(x) test_global() global y y=200 print(y)
Procedure to test the script:
- exit Pythonista
- open Pythonista and wait
- check printed x and y in console
- write 'x+y' in console to see output '210'
point 4. fails and returns : name 'x' is not defined
- Pythonista v3.1
- python 2.7.12 interpreter as default
- sorry for this
- my pythonista_startup.py is inside 'site-packages-2'
Can you help me in creating global variables using pythonista_startup?
Does y still exist in the console, just x missing? (Try dir() in console)
Can you try defining x within the global scope of pythonista_startup? before test_globals (), use x= 0, which will get overridden later.
I'm not sure whether that happens when you use
globalwithin a function, if it appears as pythonista_startup.x, which is the requirement pythonista uses for saving globals.
I forget if pythonista_startup is actually imported, vs being run as main. You may need to import pythonista_startup then set the variables there.
The other approach is to use double under prefix on globals you want to retain eg
Hi @JonB, thank you for reply.
After execution of the test script in previous post ('pythonista_startup.py'), the python console can't recognize the two global variables 'x' and 'y'. If I run manually the script 'pythonista_startup.py' Pythonista creates the global variables. So I can understand that the execution of pythonista_startup is not like a normal/manual script execution. Am I wrong?
Also if I add 'x=0' at the beginning of the test script doesn't work.
I tried to use '__x' but I can't create globals that I'd like to use in the console with an interactive mode.
My main purpose is to add actions to user key in your script about programming user keys, and I want to add actions that creates global variables when I touch the corresponding user key (this every time I launch Pythonista, so I need to create globals with pythonista_startup).
I tried also to execute a script with 'execfile(...)' in pythonista_startup but it fails to create globals.
I'm quite optimistic about existence of a solution for this, but for now I have no idea. If in the meantime you succeed, even better.
An approach is to understand what is executed by Pythonista when it is launched with an existing pythonista_startup.py script.
try placing pythonista_startup in site-packages. I am thinking, perhaps, that site-packages-2 does not retain globals like site-packages, or else globals are cleared in between.
pythonista_startup is imported at startup. simply adding
in my pythonista_startup does allow x to appear in the console. This works for both 2.7 and 3.6. You can check sys.version for things that you only want run once.
You can always stash variables, functions, etc in modules that you know dont get cleared, such as sys, or
sys.myvariable = 0
(always refer to it as sys.myvariable. adding to
__builtins__ensures it is available everywhere as sort of a global global, but be sure to name it something that won't get stepped on elesewhere )
okay, if you are trying to create a custom button in pythonista_startup, that sets a global in the console, this becomes a little tricky... im not sure which scope global would point to (the globals of pythonista_startup, or globals of the current context). ui actions get called in a seperate thread, which means it won't have access to the globals seen by the main interpreter, i think. you might try ui.in_background, which runs code in the same thread used for scripts.
Hi @JonB , you are right: 'pythonista_startup.py' in folder 'site-packages' can create globals without declaring them as global. If the script is in folder 'site-packages-2', it doesn't work.
I've tried your simple test (content of pythonista_startup.py):
and after starting Pythonista, python console recognizes the var 'x'.
If I add after x=0:
Pythonista prints twice the number 0 in console (why twice?).
Instead of 'print(x)', if I write 'print x' Pythonista prints number 0 one time, even if I use python2.7 as default.
However changing folder from 'site-packages-2' to 'site-packages' gives me some chances to create a set of global variables (that I can use in console after execution of scripts happened several hours before) when I touch user keys of the key_bar at the top of Pythonista.
My next test will be to create a 'pythonista_startup.py' script with full user_keys_bar (by you) and with a set of actions that, after execution, create a set of global variables that I need to use subsequently in python console (especially scientific calculations using sage, sorry, my usage of Pythonista is mostly based on calculus).
Thank you for your help
pythonista_startupmodule is imported by both the Python 2 and 3 interpreters. (Both are started at the same time, even if you only use one.) If you change the code to
print x, it will run in Python 2 but cause an exception in Python 3 (and all exceptions from
pythonista_startupare silently ignored).
@Matteo is trying to create a function defined in pythonista_startup which sets a global in the console. My attempts at this fail, I think because the
__globals__for such functions are actually the pythonista_startup globals. I suspect the objc that initializes the interpreter imports pythonista_startup, then copies its globals to the interpreter thread's globals...
The question is, is there a way (inspect maybe?) to find the current interpreter's globals and set things there...?
I think the Python console uses the globals of the
__main__module, which corresponds to the script that was last run. I'm not sure how exactly the globals from
pythonista_startupare initially copied into the console globals, it seems that is done in C rather than in
pykit_startup. In any case, I'm guessing this copying only happens once, so if you add globals to
pythonista_startupafterwards, they won't appear in the console. However when Pythonista clears the console globals (using
pykit_preflight) when running a new script, it does look at
pythonista_startup's globals to determine what to keep.
So I think (I haven't tested this) to add console globals after
pythonista_startuphas finished running, you need to add the global to both the
pythonista_startupmodules. If you're doing this in a function in
pythonista_startup, that means you need to declare the variable as
global, set it, and also set an attribute on
__main__with the same name.
yup, that did it: in pythonista startup:
x=0 def set_globals(sender): import sys sys.modules['__main__'].x=2
then, using that method later, say in a ui button, does set the global as seen in the console.
@JonB and @dgelessus Hi and thank you both! JonB script works and solves my issue about global variables in site-packages-2.
Now I can use this code by programming actions that execute external files with global variables creation and available in console.
Thank you again for help.
Hi, sorry but I have another problem with global variables and Pythonista 3.1 (using interpreter 2.7).
Procedure to reproduce the problem:
- create a script S1 with following code
global var var=100 print(var)
create script S2 with
execute script S1: it prints in console number 100, and if you write
varin console, it prints again 100 (the global var is alive, ok, that's what I expect).
execute script S2: if you write
varin console, interpreter says
... name 'var' is not defined, that is: global variable
varno longer exists.
Is it ok or am I wrong with something?
In S2, what happens if you put
global varbefore you use it?
I think that it is the expected behaviour. Executing in console is different from executing the script. I think that when you execute a script, existing global variables are removed before start running the script but the global variables are not removed or cleared after the script is run. If you run a script from console global variables are not removed or cleared unless you set the configuration to clear the global variables before running. That is the reason why you see the global variables of previously run script. If you run a new script from outside old global variables are removed before running the new script.
@ccc Hi, the problem is not solved with
global varat the beginning of script S2. It says: name var not defined.
But do you have the same problem with Pythonista you use?
@enceladus Hi, thank you for info, but if I want to keep alive the globals I create with different scripts execution, how can I do?
I'm trying to create a global var with execution of a script and another global var with execution of another script in ordert to use the two global variables in python console.
I do not think that it is possible to keep the global variables live across sesssions. I think you need to save them in a file before exiting and load them from the file at the start of the next session. May be you can use json for this.
@enceladus Hi, interesting, thank you for idea. So the solution could be to write a piece of code to insert at the end of any script in order to create a file with content of all global variables and this file is opened by interpreter to read content every time I switch to console window in Pythonista, not only when I launch Pythonista (using pythonista_startup).
Do you have a better idea or an existing working solution created by someonelse?
I think that if your global variable name begins with double underscore, it will not be cleared.
To be tested
Thanks @cvp . Global variables whose names start with double underscores seem to be alive across sessions.
You can also initialise these double underscore global variables in pythonista_startup as suggested by @JonB.
sys.modules['__main__'].__var = 2