How to get a modular variable in a function from another module?

I would like to define a helper function that has the ability to modify a module level variable (with a known name) from the surrounding context without explicitly passing it, for example.

# mod1.py
mod_var = 1
modify_var()
# mod_var modified
print mod_var

The problem is that I cannot refer to the variable on mod1.mod_var, because I want to use a helper function for many modules (the helper itself will be defined in another module); it must dynamically “select” mod_var from the surrounding context / call area.

Is it possible? How to get it?

My use case is to improve URL definition → display mapping in Django. These definitions are distributed across many submodules that define a level variable urlpatterns. The helper function must select this variable from the module that calls and modifies it. Avoiding explicitly passing it as an argument would be great.

Edit: For an additional solution - check this answer.


Edit2:

Wrong solution below! (left for links in the comments)

I recently found another solution (the least magical, in my opinion;)) The function modify_var()can be implemented as follows:

def modify_var():
    calling_module = __import__("__main__")
    calling_module.mod_var = 42

However, potential gains are debatable.

unittestthe module uses this method in its method main.

+3
4

, , . , Python " , ", : , , , .

, 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

, , a.py:

import evil

mod_var = 23
evil.modify_var()
print 'a mod_var now:', mod_var

b.py:

import evil

mod_var = 100
evil.modify_var()
print 'b mod_var now:', mod_var

:

$ python -c'import a; import b'
a mod_var now: 24
b mod_var now: 101

, .

+4

, , . urlpatterns . , .

+4

, , , :

import sys

def modify_var():
    """Mysteriously change `mod_var` in the caller context."""
    f = sys._getframe(1)
    f.f_locals['mod_var'] += " (modified)"

mod_var = "Hello"
modify_var()
print mod_var

:

Hello (modified)

: _getframe , Python , : " ".

+2

, mod1 , , . ; .

0

Source: https://habr.com/ru/post/1727969/


All Articles