How to get module variable in function from another module?
django, python
Solution
It's a truly bad, horrible, and awful idea, which will lead to future maintenance nightmares. However, Python does offer "enough rope to shoot yourself in the foot", if you truly insist: introspection and metaprogramming tools which are mostly intended for debugging purposes, but can be abused to perform the ill-conceived task you so desperately crave.
For example, in `evil.py`:
import inspect
def modify_var():
callersframe = inspect.stack()[1][0]
callersglobals = callersframe.f_globals
if 'mod_var' not in callersglobals:
raise ValueError, 'calling module has no "mod_var"!'
callersglobals['mod_var'] += 1
now say you have two modules, `a.py`:
import evil
mod_var = 23
evil.modify_var()
print 'a mod_var now:', mod_var
and `b.py`:
import evil
mod_var = 100
evil.modify_var()
print 'b mod_var now:', mod_var
you could do:
$ python -c'import a; import b'
a mod_var now: 24
b mod_var now: 101
However, maintaining this kind of black-magic tricks in the future is going to be a headache, so I'd strongly recommend not doing things this way.
Problem
I'd like to define a helper function that has the ability to modify a module-level variable (with known name) from surrounding context without explicitly passing it, e.g. ``` # mod1.py mod_var = 1 modify_var() # mod_var modified print mod_var ``` The problem is - I can't reference variable by `mod1.mod_var`, because I want to use helper function across many modules (helper itself will be defined in other module); it should dynamically 'pick' mod_var from surrounding calling context/scope. Is this possible? How to obtain this? My use case is to enhance defining URL -> view mapping in Django. Those definitions are spread across many sub-modules that define `urlpatterns` module-level variable. Helper function should pick this variable from the module that calls it and modify it. Avoiding explicitly passing it as argument would be great. Edit: For additional solution - check this answer. Edit2: Wrong solution below! (left for references in comments) Recently I've found another solution (the least magical in my opinion ;)) `modify_var()` function could be implemented like this: ``` def modify_var(): calling_module = __import__("__main__") calling_module.mod_var = 42 ``` Still, potential profits are arguable. `unittest` module uses this technique in its `main` method.