Let's have a.py be:
def foo():
global spam
spam = 42
return 'this'
At a console, if I simply import a
, things make sense to me:
>>> import a
>>> a.foo()
'this'
>>> a.spam
42
However, if I do the less popular thing and...
>>> from a import *
>>> foo()
'this'
>>> spam
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'spam' is not defined
>>> a.spam
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
I've read opinions about why people don't like "from module import *
" from a namespace perspective, but I can't find anything on this behavior, and frankly I figured out that this was the issue I was having by accident.
When you ask for a.spam
there happens a namespace search in the module a
and spam
is found. But when you ask for just spam
:
>>> from a import * # imported foo, spam doesn't exist yet
>>> foo()
spam
is created in the namespace a (you cannot access it with such import though), but not in the current module. And it seems like nobody promised us to add newly added globals of a
to all the namespaces module a
has been imported into via *
. That will require storing import links inside the interpreter and probably will degrade performance if one heavily imported module does such tricks all the time.
And imagine you have defined spam
in your main module prior to calling foo()
. That would be downright name collision.
Just as illustration, you can do from a import *
to get fresh updates for the module a
:
from a import *
print(foo())
from a import *
print(spam)
Let's go thorough it step by step:
At the point of importing, a
only has the symbol foo
which refers to a function.
Only if the function is executed, a
gets the additional symbol spam
.
In the first case, you do import a
and get a "handle" to the module, which allows you to monitor whatever happens later. If you'd do a.spam
before calling a.foo()
, you'd get an error.
In the second case, from a import *
gives you whatever currently is in the module - and that's just spam()
. After calling that, you could do from a import *
to get spam
as well.
I generally agree with Vovanrock2002.
As was recently explained to me, the '.' is a scope resolution operator. import a
and from a import *
give you different syntaxes. from a import *
imports each global variable from a
separately, and binds them as variables in the local scope. A more practical example might be the difference between import datetime
and from datetime import date
. With the former, I have to create a date object using datetime.date(2015, 11, 12)
, with the latter I get to just use date(2015, 11, 12)
.
You can read more on the import statement
I would have to differ with you, however, in that I don't believe that spam is the meaning of life, the universe, and everything.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With