Here's an extreme example of
import and namespace trickery, drawn
from the standard Python
try: import SOCKS socket = SOCKS del SOCKS from socket import getfqdn socket.getfqdn = getfqdn del getfqdn except ImportError: import socket
(linebreaks added for clarity)
Modules are objects in Python, so a module's name binding can be
manipulated like anything else. This leads to the two things that
ftplib is doing here.
ftplib module would like to use the
SOCKS module if it
exists and otherwise use the standard
socket module. Rather than
sprinkle conditionals throughout its own code, it just imports
and renames it to
socket, counting on
SOCKS to have all the socket
routines it needs under the same names as
SOCKS is apparently missing the
getfqdn function. So
ftplib yanks a reference to it out of the real
socket module and
stuffs it into the
SOCKS module (that
ftplib knows as '
This lets its code can just call
socket.getfqdn without having to
worry about whether
socket is the real thing or
This works because of bonus trickery: unlike other operations, both
import' and '
from <blah> import ...' take the names without
looking them up in the current namespace. So even though the name
socket' points to the
SOCKS module at this point, '
import getfqdn' goes off to the real
socket module, instead of
trying to find
getfqdn in the
Because modules are global, the side effect of this is that
SOCKS's namespace for everyone that's imported it. If
somewhere in the program another module has also imported
they can refer to '
SOCKS.getfqdn' and it will work.
(There are actually practical uses of altering other modules' namespaces. I may cover some of them in a later entry.)