Daniel Arbuckle's Mastering Python
上QQ阅读APP看书,第一时间看更新

Accessing code from other modules

We'll start off this section by understanding the difference between absolute and relative imports, then move on to writing those, and finally, we'll look at cyclic dependencies.

When we are importing one of the package's modules from outside the package, there's only one sensible way that it could work-we tell Python which package and module we want, and it either finds and imports it or raises an exception if it can't. Simple!

import packagename.modulename  

When we're already inside a package, the situation is more ambiguous because import name could just as easily mean "look for name within this package" or "look for name in the Python search path." Python breaks this ambiguity by defining import name to mean that a package or module called name should be searched for in Python's search path:

import name  

Also, it also gives us a way to specify a relative import if we'd rather have it just look within the current package. We can specify a relative import by putting a dot in front of the name of the module we want to import, as shown in the following code:

import .name  

When Python sees this, it will look for a module called name in the same package as the module our code is running in.

Often, we only need one or two objects from another module and it's more convenient to import those objects directly into our global scope than it would be to import the module as a whole and access its contents. Python lets us do that with a slight variation on the import syntax:

from .name import Foo  

Finally, sometimes we want to rename an object within our scope as we import it. We could do that by modifying our import with the as keyword:

from .name import Foo as Bar 

In the preceding example, even though the object is called Foo in the name module, in our current module, it's named Bar. This trick works for absolute imports too by the way.

Before we move on, let's take note that Python 2 used a different rule for deciding where to find imported code. In Python 2, it first tried to find a target of an import within the current package. Then, if no matching module was found there, it went out and looked for it on the search path. This approach usually did the right thing, but occasionally caused problems due to the ambiguous meaning; and it meant that we couldn't have some packages, sub-packages, or modules that shared the name of anything in the standard library or other installed packages. So, this behavior was changed in Python 3.