Python Forum

Full Version: module functions and data references
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
suppose you have a some functions in a module and two of these functions need to call the other functions. you need to call those two functions in a script.

an example module (named callers.py) to test this concept:
from __future__ import division, print_function

def a():
    print('this is a')
    return

def b():
    print('this is b')
    return

def c():
    print('this is c')
    return

def d():
    print('this is d')
    return

def x():
    print('this is x')
    a()
    b()
    return

def y():
    print('this is y')
    c()
    d()
    return
an example script that uses this:
from __future__ import division, print_function

from callers import x, y

x()
print('foobar')
y()
if you run this example script with this example module, the expected output is:
Output:
this is x this is a this is b foobar this is y this is c this is d
my question is: how are functions a,b,c, and d referenced if only x and y are imported.  i do understand (because i read it somewhere) that when "from somemodule import ..." is used, the whole module gets imported somewhere and the particular names being used are inserted into the importer script.  how do x and y find a,b,c, and d? where are the names placed?
Import is a very weird animal. The best way to learn how it works it to watch the video of the guy that re-wrote
it for Python 3, Brett Cannon his video is here: https://www.youtube.com/watch?v=Nsg886UO...W&index=15
I know that you don't like to spend the time to watch these, but this is actually an enjoyable and informative take.
well, from pure practical perspective it makes sense that if you import something (e.g x) from some module, you don't need to import everything it needs in order to work. i.e. (its 'internal dependencies). The other way would mean that you need to study the code and import every such dependency every time. Think if that is not a module written by you, but some third-party package. Do you need to know all its nuts and bolts in order to import? The import does the trick in the background and everything that x needs to work is imported however only the name x is imported/accessible in your namespace.
Somewhere I read (or may have gotten from the tutorial that Brett Cannon made)
that when you 'import from', it's only so that you can access the methods without a prefix,
that the entire module gets loaded anyway. That may have been from one of Dave Bezley's
videos, but I do believe this is the case.
It was David Beazley's video:
Quote:from module import
Lifts selected symbols out of a module after
importing
it and makes them available locally
from math import sin, cos
def rectangular(r, theta):
x = r * cos(theta)
y = r * sin(theta)
return x, y
21
Allows parts of a module to be used without
having to type the module prefix
The video for this is located here: https://www.youtube.com/watch?v=0oTh1CXRaQ0
Above is taken from the slides, page 21: http://www.dabeaz.com/modulepackage/ModulePackage.pdf
Importing something let the Interpreter parse the whole file, translate it into bytecode and then the interpreter is executing the whole file.
In fact if you're using something like:
from util import foo
The whole file util is imported as module, which lives on the heap (i think so).
Only the the function foo is assigned to the name foo, but the function foo can access to everything inside the module util.
The name foo is just a reference to the function foo inside the module util.

If you delete foo the module util, it is not garbage collected, because all modules are cached. If you importing in many different modules the same module again and again, you'll get exactly the same version of the module.
i have modified the code to show some more information.

the module callers.py:
from __future__ import division, print_function

from_callers_which_namespace_will_this_assignment_be_put_in = 'from callers which namespace will this assignment be put in ?'

def a():
    print('this is a')
    return

def b():
    print('this is b')
    return

def c():
    print('this is c')
    return

def d():
    print('this is d')
    return

def x():
    print('this is x')
    
    from_x_which_namespace_will_this_assignment_be_put_in = 'from x which namespace will this assignment be put in ?'[:-2]

    print('in x locals keys =',repr(locals().keys()))
    print('in x globals keys =',repr(globals().keys()))

    a()
    b()
    return

def y():
    print('this is y')
    c()
    d()
    return
the script:
from __future__ import division, print_function

from callers import x, y

which_namespace_will_this_assignment_be_put_in = 'which namespace will this assignment be put in ?'[:-2]

print('locals keys =',repr(locals().keys()))
print('globals keys =',repr(globals().keys()))

x()
print('foobar')
y()
and the new output:
Output:
locals keys = ['division', 'which_namespace_will_this_assignment_be_put_in', '__builtins__', '__file__', '__package__', 'x', 'y', '__name__', '__doc__', 'print_function'] globals keys = ['division', 'which_namespace_will_this_assignment_be_put_in', '__builtins__', '__file__', '__package__', 'x', 'y', '__name__', '__doc__', 'print_function'] this is x in x locals keys = ['from_x_which_namespace_will_this_assignment_be_put_in'] in x globals keys = ['a', 'division', 'c', 'b', 'd', '__builtins__', '__file__', '__package__', 'from_callers_which_namespace_will_this_assignment_be_put_in', 'x', 'y', '__name__', '__doc__', 'print_function'] this is a this is b foobar this is y this is c this is d
when the script is running it has one namespace referenced both as local and as global.  when i think about it, the script just had code not in a function so there was only one context, anyway.  but in function x we see where its own symbols are referenced from.  and we can see that division and print_function are visible.