pythonpython-3.xruntimeside-effectsdynamic-scope

Get reference to a namespace where the function was called


Is there a general way in Python 3 to get a reference to the module's namespace where the function was called? The problem arises from the fact that global in function references to the namespace where the function was defined, but I want to obtain the reference to a namespace where it was called like in languages with dynamic scope.

In reality, I want to pollute the current namespace with predefined values during an interactive session, the similar to from module import * but with the call to set_state().

from state import set_state
set_state()

The from module import * syntax is not enough because I have several configurations which are accessed like set_state(3). I know that I can pass locals() as an argument to the function. Nevertheless, I think there exists a more general solution. Also the answer should not be restricted to the current use case.


Solution

  • Yes you can with the inspect module, example:

    test.py

    import os
    import sys
    import inspect
    
    def my_function():
        print ('Module/Function : ' + os.path.basename(__file__) + ' ' + sys._getframe().f_code.co_name +'()') 
        print ('Called from     : ' + os.path.basename(inspect.stack()[1][1]) +' ' + inspect.stack()[1][3] + '()' )  
    

    you can now import test from another module, and call the function.

    test2.py

    import test
    
    def my_test_function():
        test.my_function()
    
    my_test_function()
    

    output:

    Module/Function : test.py my_function()
    Called from     : test.py <module>()
    Module/Function : test.py my_function()
    Called from     : test2.py my_test_function()
    

    the first two are during import, the last two output lines are when you call them from test2.py