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.