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.
You can't take my globals from me!
-
The new
pythonista_startup
feature is nice. The fact that any globals coming frompythonista_startup
aren't removed is also nice. Especially because I can now do this:from __future__ import division, print_function import sys import types class ContainAllTheThings(list): def __getitem__(self, key): try: return super(ContainAllTheThings, self).__getitem__(key) except (IndexError, KeyError): return None def __contains__(self, obj): return super(ContainAllTheThings, self).__contains__(obj) or True class DirAllTheThings(types.ModuleType): def __dir__(self): return ContainAllTheThings() new_module = DirAllTheThings(__name__, __doc__) vars(new_module).update(vars(sys.modules["pythonista_startup"])) sys.modules["pythonista_startup"] = new_module
(Can't we just have an option to keep all globals?
;)
) -
Hehe, very clever! :)
-
Can you explain it? can't tell what it does.
-
@Webmaster4o said:
Can you explain it? can't tell what it does.
Every time you run a script, Pythonista deletes all global variables, except for those that come from the
pythonista_startup
module (which is run automatically when the app is started). Internally this is done by looking atdir(pythonista_startup)
- any names listed there are not deleted from the globals. I'm abusing this feature just a tiny bit so that no globals are ever removed.The first class,
ContainAllTheThings
, is a subclass oflist
that pretends to contain every object, i. e.obj in ContainAllTheThings()
is alwaysTrue
for any object. The second class,DirAllTheThings
, is a subclass ofmodule
(akatypes.ModuleType
) with a modified__dir__
method that returns aContainAllTheThings
object. This means thatobj in dir(DirAllTheThings())
is alwaysTrue
. Finally we replace the real modulepythonista_startup
with aDirAllTheThings
object and copy all attributes over.To find out which global names come from
pythonista_startup
, Pythonista internally checksname in dir(pythonista_startup)
for every name. Now we've replacedpythonista_startup
with an instance ofDirAllTheThings
, meaning that when we calldir
on it we get an instance ofContainAllTheThings
. Now when Pythonista checks whether a name comes frompythonista_startup
, the answer is alwaysTrue
, meaning that no name is ever deleted. -
Ah. Clever!
-
The original version no longer works in Pythonista 3. It seems that the
dir
function now converts the return value of__dir__
to an actual list, instead of allowing a subclass. This is the updated version:import sys import types class DirAllTheGlobals(types.ModuleType): import __main__ def __dir__(self): return dir(type(self).__main__) # THESE LINES MUST COME LAST. # Anything past this point is executed in the context of the old # pythonista_startup module, which may already be partially # garbage-collected. new_module = DirAllTheGlobals(__name__, __doc__) vars(new_module).update(vars(sys.modules["pythonista_startup"])) sys.modules["pythonista_startup"] = new_module
This should also still work in Pythonista 2.
@omz please can you add the option to keep globals back?