|I l@ve RuBoard|
Modules are probably best understood as places to define names you want visible to the rest of a system. In Python-speak, modules are a namespace梐 place where names are created. And names that live in a module are called its attributes. Technically, modules correspond to files, and Python creates a module object to contain all the names defined in the file; but in simple terms, modules are just namespaces.
So how do files become namespaces? Every name that is assigned a value at the top level of a module file (i.e., not in a function body) becomes an attribute of that module. For instance, given an assignment statement such as X=1 at the top level of a module file M.py, the name X becomes an attribute of M, which we can refer to from outside the module as M.X. The name X also becomes a global variable to other code inside M.py, but we need to explain the notion of module loading and scopes a bit more formally to understand why:
The first time a module is imported anywhere in a system, Python creates an empty module object and executes the statements in the module file one after another, from the top of the file to the bottom.
During an import, statements at the top-level of the file that assign names (e.g., =, def) create attributes of the module object; assigned names are stored in the module's namespace.
Module namespaces created by imports are dictionaries; they may be accessed through the built-in __ dict __ attribute associated with module objects and may be inspected with the dir function we met in Chapter 1.
As we saw in Chapter 4, names at the top level of a module follow the same reference/assignment rules as names in a function, but the local and global scopes are the same (or, if you prefer, the LGB rule, without the G). But in modules, the local scope becomes an attribute dictionary of a module object, after the module has been loaded. Unlike functions (where the local namespace exists only while the function runs), a module file's scope becomes a module object's attribute namespace and may be used after the import.
Let's look at an example of these ideas. Suppose we create the following module file with our favorite text editor and call it module2.py :
print 'starting to load...' import sys name = 42 def func(): pass class klass: pass print 'done loading.'
The first time this module is imported (or run as a program), Python executes its statements from top to bottom. Some statements create names in the module's namespace as a side effect, but others may do actual work while the import is going on. For instance, the two print statements in this file execute at import time:
>>> import module2 starting to load... done loading.
But once the module is loaded, its scope becomes an attribute namespace in the module object we get back from import; we access attributes in the namespace by qualifying them with the name of the enclosing module:
>>> module2.sys <module 'sys'> >>> module2.name 42 >>> module2.func, module2.klass (<function func at 765f20>, <class klass at 76df60>)
Here, sys, name, func, and klass were all assigned while the module's statements were being run, so they're attributes after the import. We'll talk about classes in Chapter 6, but notice the sys attribute; import statements really assign module objects to names (more on this later). Internally, module namespaces are stored as dictionary objects. In fact, we can access the namespace dictionary through the module's __dict__ attribute; it's just a normal dictionary object, with the usual methods:
>>> module2.__dict__.keys() ['__file__', 'name', '__name__', 'sys', '__doc__', '__builtins__', 'klass', 'func']
The names we assigned in the module file become dictionary keys internally. As you can see, some of the names in the module's namespace are things Python adds for us; for instance, _ _file__ gives the name of the file the module was loaded from, and __name__ gives its name as known to importers (without the .py extension and directory path).
Now that you're becoming familiar with modules, we should clarify the notion of name qualification. In Python, you can access attributes in any object that has attributes, using the qualification syntax object.attribute. Qualification is really an expression that returns the value assigned to an attribute name associated with an object. For example, the expression module2.sys in the next-to-last example fetches the value assigned to sys in module2. Similarly, if we have a built-in list object L, L.append returns the method associated with the list.
So what does qualification do to the scope rules we saw in Chapter 4? Nothing, really: it's an independent concept. When you use qualification to access names, you give Python an explicit object to fetch from. The LGB rule applies only to bare, unqualified names. Here are the rules:
"X" means search for name X in the current scopes (LGB rule)
"X.Y" means search for attribute Y in the object X (not in scopes)
"X.Y.Z" means look up name Y in object X, then look up Z in object X.Y
Qualification works on all objects with attributes: modules, classes, C types, etc.
In Chapter 6, we'll see that qualification means a bit more for classes (it's also the place where inheritance happens), but in general, the rules here apply to all names in Python.
|I l@ve RuBoard|