Learning Python - Mark Lutz [326]
del modulename # Don't keep original name
After such an import, you can (and in fact must) use the name listed after the as to refer to the module. This works in a from statement, too, to assign a name imported from a file to a different name in your script:
from modulename import attrname as name
This extension is commonly used to provide short synonyms for longer names, and to avoid name clashes when you are already using a name in your script that would otherwise be overwritten by a normal import statement:
import reallylongmodulename as name # Use shorter nickname
name.func()
from module1 import utility as util1 # Can have only 1 "utility"
from module2 import utility as util2
util1(); util2()
It also comes in handy for providing a short, simple name for an entire directory path when using the package import feature described in Chapter 23:
import dir1.dir2.mod as mod # Only list full path once
mod.func()
Modules Are Objects: Metaprograms
Because modules expose most of their interesting properties as built-in attributes, it’s easy to write programs that manage other programs. We usually call such manager programs metaprograms because they work on top of other systems. This is also referred to as introspection, because programs can see and process object internals. Introspection is an advanced feature, but it can be useful for building programming tools.
For instance, to get to an attribute called name in a module called M, we can use qualification or index the module’s attribute dictionary, exposed in the built-in __dict__ attribute we met briefly in Chapter 22. Python also exports the list of all loaded modules as the sys.modules dictionary (that is, the modules attribute of the sys module) and provides a built-in called getattr that lets us fetch attributes from their string names (it’s like saying object.attr, but attr is an expression that yields a string at runtime). Because of that, all the following expressions reach the same attribute and object:
M.name # Qualify object
M.__dict__['name'] # Index namespace dictionary manually
sys.modules['M'].name # Index loaded-modules table manually
getattr(M, 'name') # Call built-in fetch function
By exposing module internals like this, Python helps you build programs about programs.[54] For example, here is a module named mydir.py that puts these ideas to work to implement a customized version of the built-in dir function. It defines and exports a function called listing, which takes a module object as an argument and prints a formatted listing of the module’s namespace:
"""
mydir.py: a module that lists the namespaces of other modules
"""
seplen = 60
sepchr = '-'
def listing(module, verbose=True):
sepline = sepchr * seplen
if verbose:
print(sepline)
print('name:', module.__name__, 'file:', module.__file__)
print(sepline)
count = 0
for attr in module.__dict__: # Scan namespace keys
print('%02d) %s' % (count, attr), end = ' ')
if attr.startswith('__'):
print(' else: print(getattr(module, attr)) # Same as .__dict__[attr] count += 1 if verbose: print(sepline) print(module.__name__, 'has %d names' % count) print(sepline) if __name__ == '__main__': import mydir listing(mydir) # Self-test code: list myself Notice the docstring at the top; as in the prior formats.py example, because we may want to use this as a general tool, a docstring is coded to provide functional information accessible via __doc__ attributes or the help function (see Chapter 15 for details): >>> import mydir >>> help(mydir) Help on module mydir: NAME mydir - mydir.py: a module that lists the namespaces of other modules FILE c:\users\veramark\mark\mydir.py FUNCTIONS listing(module, verbose=True) DATA sepchr = '-' seplen = 60 I’ve also provided self-test logic at the bottom of this module, which narcissistically imports and lists itself. Here’s the sort of output produced in Python 3.0 (to use this in 2.6, enable 3.0 print calls with the __future__ import described