Why import when you need to use the full name?
In python, if you need a module from a different package you have to import it. Coming from a Java background, that makes sense.
import foo.bar
What doesn't make sense though, is why do I need to use the full name whenever I want to use bar? If I wanted to use the full name, why 开发者_StackOverflowdo I need to import? Doesn't using the full name immediately describe which module I'm addressing?
It just seems a little redundant to have from foo import bar
when that's what import foo.bar
should be doing. Also a little vague why I had to import when I was going to use the full name.
The thing is, even though Python's import
statement is designed to look similar to Java's, they do completely different things under the hood. As you know, in Java an import
statement is really little more than a hint to the compiler. It basically sets up an alias for a fully qualified class name. For example, when you write
import java.util.Set;
it tells the compiler that throughout that file, when you write Set
, you mean java.util.Set
. And if you write s.add(o)
where s
is an object of type Set
, the compiler (or rather, linker) goes out and finds the add
method in Set.class
and puts in a reference to it.
But in Python,
import util.set
(that is a made-up module, by the way) does something completely different. See, in Python, packages and modules are not just names, they're actual objects, and when you write util.set
in your code, that instructs Python to access an object named util
and look for an attribute on it named set
. The job of Python's import
statement is to create that object and attribute. The way it works is that the interpreter looks for a file named util/__init__.py
, uses the code in it to define properties of an object, and binds that object to the name util
. Similarly, the code in util/set.py
is used to initialize an object which is bound to util.set
. There's a function called __import__
which takes care of all of this, and in fact the statement import util.set
is basically equivalent to
util = __import__('util.set')
The point is, when you import a Python module, what you get is an object corresponding to the top-level package, util
. In order to get access to util.set
you need to go through that, and that's why it seems like you need to use fully qualified names in Python.
There are ways to get around this, of course. Since all these things are objects, one simple approach is to just bind util.set
to a simpler name, i.e. after the import
statement, you can have
set = util.set
and from that point on you can just use set
where you otherwise would have written util.set
. (Of course this obscures the built-in set
class, so I don't recommend actually using the name set
.) Or, as mentioned in at least one other answer, you could write
from util import set
or
import util.set as set
This still imports the package util
with the module set
in it, but instead of creating a variable util
in the current scope, it creates a variable set
that refers to util.set
. Behind the scenes, this works kind of like
_util = __import__('util', fromlist='set')
set = _util.set
del _util
in the former case, or
_util = __import__('util.set')
set = _util.set
del _util
in the latter (although both ways do essentially the same thing). This form is semantically more like what Java's import
statement does: it defines an alias (set
) to something that would ordinarily only be accessible by a fully qualified name (util.set
).
You can shorten it, if you would like:
import foo.bar as whateveriwant
Using the full name prevents two packages with the same-named submodules from clobbering each other.
There is a module in the standard library called io
:
In [84]: import io
In [85]: io
Out[85]: <module 'io' from '/usr/lib/python2.6/io.pyc'>
There is also a module in scipy
called io
:
In [95]: import scipy.io
In [96]: scipy.io
Out[96]: <module 'scipy.io' from '/usr/lib/python2.6/dist-packages/scipy/io/__init__.pyc'>
If you wanted to use both modules in the same script, then namespaces are a convenient way to distinguish the two.
In [97]: import this
The Zen of Python, by Tim Peters
...
Namespaces are one honking great idea -- let's do more of those!
in Python, importing doesn't just indicate you might use something. The import actually executes code at the module level. You can think of the import as being the moment where the functions are 'interpreted' and created. Any code that is in the _____init_____.py level or not inside a function or class definition happens then.
The import also makes an inexpensive copy of the whole module's namespace and puts it inside the namespace of the file / module / whatever where it is imported. An IDE then has a list of the functions you might be starting to type for command completion.
Part of the Python philosophy is explicit is better than implicit. Python could automatically import the first time you try to access something from a package, but that's not explicit.
I'm also guessing that package initialization would be much more difficult if the imports were automatic, as it wouldn't be done consistently in the code.
You're a bit confused about how Python imports work. (I was too when I first started.) In Python, you can't simply refer to something within a module by the full name, unlike in Java; you HAVE to import the module first, regardless of how you plan on referring to the imported item. Try typing math.sqrt(5)
in the interpreter without importing math
or math.sqrt
first and see what happens.
Anyway... the reason import foo.bar
has you required to use foo.bar
instead of just bar
is to prevent accidental namespace conflicts. For example, what if you do import foo.bar
, and then import baz.bar
?
You could, of course, choose to do import foo.bar as bar
(i.e. aliasing), but if you're doing that you may as well just use from foo import bar
. (EDIT: except when you want to import methods and variables. Then you have to use the from ... import ...
syntax. This includes instances where you want to import a method or variable without aliasing, i.e. you can't simply do import foo.bar
if bar
is a method or variable.)
Other than in Java, in Python import foo.bar
declares, that you are going to use the thing referred to by foo.bar
.
This matches with Python's philosophy that explicit is better than implicit. There are more programming languages that make inter-module dependencies more explicit than Java, for example Ada.
Using the full name makes it possible to disambiguate definitions with the same name coming from different modules.
You don't have to use the full name. Try one of these
from foo import bar
import foo.bar as bar
import foo.bar
bar = foo.bar
from foo import *
A few reasons why explicit imports are good:
- They help signal to humans and tools what packages your module depends on.
- They avoid the overhead of dynamically determining which packages have to be loaded (and possibly compiled) at run time.
- They (along with sys.path) unambiguously distinguish symbols with conflicting names from different namespaces.
- They give the programmer some control of what enters the namespace within which he is working.
精彩评论