0

I thought I understood what "import *" did and its potential dangers, but obviously not.

I've got:

foo.py:

from datetime import datetime
from bar import *
print(datetime.now())

bar.py:

import datetime

The result of running foo.py is an exception:

AttributeError: module 'datetime' has no attribute 'now'

datetime is a module, but datetime.datetime is a type. from datetime import datetime makes it so that datetime in foo.py refers to the type, but the subsequent from bar import * somehow makes it again refer to the module.

Removing the from bar import * makes the exception go away.

But why does from bar import * pollute my namespace with the module datetime? datetime is a module imported in bar, but it isn't defined there. What am I missing?

aggieNick02
  • 2,557
  • 2
  • 23
  • 36

1 Answers1

4

The bar module does define a name datetime. The statement

import datetime

creates a module-level datetime variable in the bar module and binds the variable to the datetime module. import * picks up this name the same way it picks up other names.

import * doesn't care about where objects were created. It doesn't care that the datetime module itself comes from some other file. A datetime name exists in bar, so that name gets imported.

user2357112
  • 260,549
  • 28
  • 431
  • 505
  • Thanks for the explanation; it makes sense. I guess I thought that modules from imports were somehow not picked up from an import *, but with your explanation, I guess that would be even weirder. – aggieNick02 Jan 17 '19 at 00:20