Reputation: 183519
I need some clarification on how module and class level imports are handled when coexisting in the same namespace. See the following examples:
Works:
import datetime
print datetime.datetime.utcnow()
Fails:
from datetime import datetime
print datetime.datetime.utcnow()
Error: AttributeError: type object 'datetime.datetime' has no attribute 'datetime'
Works:
from datetime import datetime # Is this ignored?
import datetime
print datetime.datetime.utcnow()
What exactly is happening in the 3rd example? Is the second module import replacing the class-specific first import? Does this mean that module and class level imports shouldn't be mixed in the same namespace?
Upvotes: 2
Views: 790
Reputation: 500327
There is no priority is such. The outcome is determined by the order in which import
statements are executed, as follows.
If you try to import several things called X
into your namespace, each import would rebind X
to whatever it's importing.
Therefore at the end it will be last import that'll be in effect as far as the name X
in concerned.
This is precisely what happens in your third example:
from datetime import datetime # This isn't ignored, but the name is immediately rebound
# by the next line
import datetime # Rebinds the name
Upvotes: 6
Reputation: 26150
Your first example imports the datetime
module and provides a datetime
label in the local namespace representing it, then calls the utcnow()
method of the datetime
object belonging to the datetime
module. The second adds the datetime.datetime
object (not the module) to the local namespace with the label datetime
, but the datetime
object has no attribute datetime
, so you get the exception. The third example assigns the datetime.datetime
object to the label of that name in the namespace, then reassigns the label to the datetime
module. So ignoring the mechanics of import
that are irrelevant to this question (basically, adding modules to sys.modules
if they are not there yet), what you have is equivalent to:
datetime = sys.modules['datetime']
datetime.datetime.utcnow()
then
datetime = sys.modules['datetime'].datetime
datetime.datetime.utcnow()
then
datetime = sys.modules['datetime'].datetime
datetime = sys.modules['datetime']
datetime.datetime.utcnow()
Upvotes: 0
Reputation: 599580
An import is really just an assignment: it sets a name in your current namespace. So, in the third case, you set the name datetime
as equal to the datetime class, then immediately reassign it to the datetime module.
Upvotes: 2
Reputation: 7490
There is no reason to do it like this:
from datetime import datetime
print datetime.datetime.utcnow()
this code, on the other hand, would do exactly what you want it to:
from datetime import datetime
print datetime.utcnow()
Upvotes: 0
Reputation: 47988
Some of the IDE's that support python would give you the explanation, but yes, you're redefining (overwriting, replacing) the import in the 3rd example. Each name within a file is distinct. If you need access to a module and a class that share a name you need to use something like from datetime import datetime as dt
.
Upvotes: 2