Keep away from from some_module import *
because you import all names from that module into your current module namespace.
This will - in case of a "name clash" - not only overwrite any previously defined names but they are also, as you've seen, likely to be overwritten.
Why is that?
The from fake import *
in your case is very roughly equivalent to:
# equivalent to "from fake import *"
import fake
a = fake.a
b = fake.b
del fake
# Rest of the file
a = "real a"
print(a, b)
So no wonder that the "fake a"
isn't accessible (nor printed).
Do I have to use import fake
and fake.a
?
That's a good start if you want to "reduce" the likelyhood of such name collisions:
import fake
a = "real a"
print(a, fake.a, fake.b)
But you could also use an alias:
import fake as f
a = "real a"
print(a, f.a, f.b)
You could also import specific names from fake
(also with aliases):
from fake import a as fake_a, b as fake_b
a = "real a"
print(a, fake_a, fake_b)
As for
What if I want to use a
in fake.py
?
There should be no problem because there is no import in fake.py
so no name collision there.