9

From the documentation:

The wild card form of import — from module import * — is only allowed at the module level. Attempting to use it in class or function definitions will raise a SyntaxError.

Why? What's the sense of avoiding to use it in a function? What's the problem?

user2864740
  • 60,010
  • 15
  • 145
  • 220
zer0uno
  • 7,521
  • 13
  • 57
  • 86

1 Answers1

10

The CPython implementation uses a special optimisation for local variables: They aren't dynamically looked up at runtime from a dictionary, as globals are, but rather are assigned indices statically at compile time, and are looked up by index at runtime, which is a lot faster. This requires the Python compiler to be able to identify all local names at compile time, which is impossible if you have a wildcard import at function level.

In Python 2, there was still a fallback mechanism that got invoked in cases where it wasn't always possible to determine all local names statically. This mechanism used a dynamic dictionary for local variables, significantly slowing down execution.

For example this code

def f():
    exec "x = 2"
    print x

works as expected in Python 2, whereas

def f():
    exec("x = 2")
    print(x)

results in a NameError in Python 3.

Sven Marnach
  • 574,206
  • 118
  • 941
  • 841
  • So if I'm getting it the right way: during the compiling time, for local scopes, Python locates all the variables used and stores them in a table; instead for globals Python modifies the dictionary that contains all global names at runtime. In a function we can't use the wildcard because, using Python a static mechanism, then it should find and compile all the modules imported in the functions and those modules imported in those modules. Is that right? – zer0uno Jan 22 '15 at 17:03
  • @antox: Yes, that's right. And since global variables are dynamic, they can even be dynamically created at runtime, e.g. by modifying the `globals()` dictionary or by using `exec()`, so it's outright impossible to statically determine all the names that might get imported. – Sven Marnach Jan 22 '15 at 17:09
  • @sven_marnach Ok, just one question. You said that in Python2 they used a double mechanism, the first static and the second dynamic as a fallback. Couldn't they use a sort of this behavior for globals too? beause I understand that 'statically' optimazes the program, so they use a static strategy, but in case you wanna do `exec("x=2")` the engine falls back on the second strategy – zer0uno Jan 22 '15 at 17:11
  • 1
    I mean, is the dynamic mechanism that slows down or is the entire mechanism of switching from static to dynamic mechanism that slows down? – zer0uno Jan 22 '15 at 17:28
  • @antox: Implementing this for globals is difficult to do without changing language sematics. E.g. you would have to detect statically whether someone is calling `globals()`. Moreover, it will probably pay off less for globals, since most variable look-ups in loops are for locals. If you want to micro-optimize your code, you can lift global variables into the global scope. – Sven Marnach Jan 22 '15 at 18:04