11

There's a part of __import__ in Python documentation, which I don't understand:

__import__(name[, globals[, locals[, fromlist[, level]]]])

The function imports the module name, potentially using the given globals and locals to determine how to interpret the name in a package context. The standard implementation does not use its locals argument at all, and uses its globals only to determine the package context of the import statement.

What is there to "interpret" about the module name? What is package context?

An example call using those parameters looks like this:

spam = __import__('spam', globals(), locals(), [], -1)

Why does the example provide globals() and locals() to the function? What happens when I only provide globals()? Or neither?

I am probably missing some part of the namespace logic with relation to importing modules. Could you point me to an article that explains this/has examples with __import__ function?

Mogsdad
  • 44,709
  • 21
  • 151
  • 275
Martin Tóth
  • 1,747
  • 3
  • 24
  • 35
  • 1
    Shouldn't this question be moved to StackOverflow? – Eric O. Lebigot Feb 02 '11 at 09:52
  • This is funny, I started to write this at SO, but was thinking whether I should post it on programmers.SE instead... I clearly need to look at FAQs... – Martin Tóth Feb 02 '11 at 09:56
  • You should select one of the below answers as the accepted answer for this question. IMHO, 9000's answer hits the nail on the head by explaining what Python does with `globals` to determine the module namespace. – Kumba Oct 16 '12 at 04:14

3 Answers3

6

The standard implementation does not use its locals argument at all, and uses its globals only to determine the package context of the import statement.

(from docs.python.org)

I still have no idea how globals are used; what global variable can ever affect the way import statement works?

EDIT: After looking at import.c in Python 2.5 source I found that __import__ expects to find either __name__ or __path__ in globals in order to augment import search path relative to path(s) found in one of these variables, in that order.

9000
  • 39,899
  • 9
  • 66
  • 104
  • Talk about obtuse. So basically, instead of passing this massive blob of memory around containing all the globals (assuming Python doesn't do it by reference), one can simple pass a dict with a single key, `"__name__"`, set to the calling module's `__name__` attribute, and Python will work with it. The Python documentation should be updated with this tidbit of information. – Kumba Oct 16 '12 at 03:31
  • @Kumba: assume that Python does most everything by reference, except some primitive numeric operations. Dicts are definitely passed by reference. Python 3.3 even introduces an implementation of dicts that share keys, that is, keys are accessed by reference, too. Talk about cache coherence if you want to grumble :) – 9000 Oct 16 '12 at 13:07
  • Having actually played on (and owning) non-cache-coherent hardware, I can only begin to imagine that nightmare. Thankfully (or sadly, take your pick), the code I wrote in Python has to run on, at least, Python 2.4. I've avoided 3.x because I know it completely up-ended the language and a lot of my code probably wouldn't work w/o serious rewrite. – Kumba Oct 17 '12 at 02:14
2

globals is used to determine the current context on where the import is being called. For example:

"""
/myproject/a/b.py
/myproject/a/foo.py
/myproject/c/d.py
/myproject/c/foo.py
"""

# Which foo gets imported?

import foo #1
foo = __import__('foo') #2

They are not the same, since there is no (easy) way on #2 to know from which module the import is being called from. The __import__ function needs to know which is the current module to actually import the correct foo.

Internally on __import__(), globals is used to get the reference on the current module invoking the import. From the __import__ source code:

Return the package that an import is being performed in. If globals comes from the module foo.bar.bat (not itself a package), this returns the sys.modules entry for foo.bar. If globals is from a package's init.py, the package's entry in sys.modules is returned, as a borrowed reference.

vz0
  • 32,345
  • 7
  • 44
  • 77
  • Let's say that there's `import foo` in `b.py` and `d.py`. How does Python not know which one to import? In case of `b.py`, why would it look for `foo` in `../c`/? – Martin Tóth Feb 02 '11 at 13:09
  • If there's `import foo` in `/myproject/e.py`, that one should't work. Either `import a.foo` or `import c.foo`. I'm sorry... I can't seem to produce an example which would "cause trouble", could you give me a hint? – Martin Tóth Feb 02 '11 at 13:15
-2

What is there to "interpret" about the module name? What is package context?

When you enter

>>> a

Python must "interpret" that name. Is it a global? Is it a local?

>>> def f(x):
...    return x * a

Now, x is clearly local. a has to be "interpreted". Global? Local?

Why does the example provide globals() and locals() to the function? What happens when I only provide globals()? Or neither?

Try it and see. Seriously. It's easier to play with it than it is to ask.

What's important is that things you do at the >>> prompt are global.

You'll need to define functions that will create a local context so you can see the differences between global and local.

S.Lott
  • 384,516
  • 81
  • 508
  • 779
  • The grim^W funny truth is that a module being imported ignores nearly global values of the module that does the import, and `__import__` fully ignores the `locals` parameter. Otherwise, you're correct :) – 9000 Feb 02 '11 at 13:03