Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
Create global variables in pythonista_startup
-
(why twice?)
Because the
pythonista_startup
module 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 toprint x
, it will run in Python 2 but cause an exception in Python 3 (and all exceptions frompythonista_startup
are 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 frompythonista_startup
are initially copied into the console globals, it seems that is done in C rather than inpykit_startup
. In any case, I'm guessing this copying only happens once, so if you add globals topythonista_startup
afterwards, they won't appear in the console. However when Pythonista clears the console globals (usingpykit_preflight
) when running a new script, it does look atpythonista_startup
's globals to determine what to keep.So I think (I haven't tested this) to add console globals after
pythonista_startup
has finished running, you need to add the global to both the__main__
andpythonista_startup
modules. If you're doing this in a function inpythonista_startup
, that means you need to declare the variable asglobal
, 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.
Regards
Bye -
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
print("Hello")
-
execute script S1: it prints in console number 100, and if you write
var
in console, it prints again 100 (the global var is alive, ok, that's what I expect). -
execute script S2: if you write
var
in console, interpreter says... name 'var' is not defined
, that is: global variablevar
no longer exists.
Is it ok or am I wrong with something?
Thanks
-
In S2, what happens if you put
global var
before 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 var
at the beginning of script S2. It says: name var not defined.But do you have the same problem with Pythonista you use?
Thanks -
@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.
Thanks
-
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?Thanks
-
-
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
-
There is another option, which is to disable global clearing, using @dgelessus 's pythonista startup
see
https://github.com/dgelessus/pythonista_startup/blob/master/init.pyand uncomment the section indicated. This replaces the pythonista_startup with a fake module that lists all globals, thus preventing clearing.
-
@cvp @enceladus and @JonB , thank you for feedback, it is undoubtedly nice that there is a sharing of ideas and solutions.
So, synthesizing, a solution for my problem is a mix of double
__
at the beginning of var name and the use ofsys.modules['__main__'].__varname=__varname
in external script executed by a user key defined by @JonB scriptStatusBarMenu
.For those interested, in order to use this script as
pythonista_startup
with the global variables creation feature using user keys, the procedure is the follow:- At line 181 of this script in place of
def a(sender) print('action from bar1')
insert
def a(sender) import sys, os doc_path = os.path.expanduser('~/Documents/tests') #in folder 'tests' I have my external script to execute by touching user key of JonB script os.chdir(doc_path) sys.path.append(doc_path) execfile('my-script-a.py') # 'my-script-a.py' is inside folder '/tests' app.keyWindow().rootViewController().showAccessoryWithAnimationDuration_(0.5)
- Then create
my-script-a.py
in folder~/Documents/tests
with following content (for example):
import sys __var = 100 sys.modules['__main__'].__var=__var print(__var)
Well, now when you touch user key of
StatusBarMenu
related to action a, Pythonista should execute the scriptmy-script-a.py
and the variable__var
lives in console also after execution of other external scripts and the var can be used inside other external scripts, as it is 100% global now.My next step is to adapt this solution for sage_interface in order to be able, using user keys with this, to execute different scripts with remote server by sagemathcell (with scipy and other tools not present in Pythonista) and to use global variables, with different names similar to filename of the executed script by sage (to not overwrite content in variables that could be useful during further calculations), in console or in other scripts. For example, if I must execute remotely with sage a script named 'optimization.py' that calculates A and an other script named 'fit.py' that calculates B, the global variables with output of A and B live in console and the name of the global variables could be '__sage-out--optimization' and '__sage-out--fit', and with the powerful word completion feature of Pythonista them can be recalled easly from python console.
Best regards
-
@Matteo If you use the DirAllTheGlobals approach, you can avoid using double underscores, though might still need to set sys.modules['main'].varname from r anythingyou want to save from within startup itself.
-
@JonB Hi JonB, i will try with option you have described, when finish i will post here a working solution,
Regards -
https://docs.python.org/3/library/os.html#os.environ and https://docs.python.org/3/library/os.html#os.getenv might also be worth looking into.