python2unit3
python2unit3
We can perform data hiding in Python using the __ double underscore before prefix. This makes
the class members private and inaccessible to the other classes.
As we've seen, Python modules export all names assigned at the top level of their file. There is
no notion of declaring which names should and shouldn't be visible outside the module. In fact,
there's no way to prevent a client from changing names inside a module if they want to.
In Python, data hiding in modules is a convention, not a syntactical constraint. If you want to
break a module by trashing its names, you can, but we have yet to meet a programmer who
would want to. Some purists object to this liberal attitude towards data hiding and claim that it
means Python can't implement encapsulation. However, encapsulation in Python is more about
packaging than about restricting.
A module can achieve a hiding effect similar to the _X naming convention, by assigning a list of
variable name strings to the variable __all__ at the top level of the module. For example:
This statement should generally appear at the top of a module file (possibly after a docstring),
because it enables special compilation of code on a per-module basis. It's also possible to submit
this statement at the interactive prompt to experiment with upcoming language changes; the
feature will then be available for the rest of the interactive session.
Here's a special module-related trick that lets you both import a file as a module, and run it as a
standalone program. Each module has a built-in attribute called __name__, which Python sets
automatically as follows:
o If the file is being run as a top-level program file, __name__ is set to the string
"__main__" when it starts.
o If the file is being imported, __name__ is instead set to the module's name as known by
its clients.
The upshot is that a module can test its own __name__ to determine whether it's being run or
imported. For example, suppose we create the following module file, named runme.py, to export
a single function called tester:
def tester( ): print "It's Christmas in Heaven..." if __name__ == '__main__': # Only when
run tester( ) # Not when imported
This module defines a function for clients to import and use as usual:
You can use this to dynamically configure a search path inside a Python program. Be careful: if
you delete a critical directory from the path, you may lose access to critical utilities. In the last
command in the example, we no longer have access to the string module, since we deleted the
Python source library's directory from the path. Also remember that such settings only endure for
the Python session or program that made them; they are not retained after Python exits.
o You're always in a module in Python. There's no way to write code that doesn't live in
some module. In fact, code typed at the interactive prompt really goes in a built-in
module called __main__; the only unique things about the interactive prompt is that code
runs and is disgarded immediately, and that expression results are printed.
o Minimize module coupling: global variables. Like functions, modules work best if they're
written to be closed boxes. As a rule of thumb, they should be as independent of global
names in other modules as possible.
o Maximize module cohesion: unified purpose. You can minimize a module's couplings by
maximizing its cohesion; if all the components of a module share its general purpose,
you're less likely to depend on external names.
o Modules should rarely change other modules' variables. It's perfectly okay to use globals
defined in another module (that's how clients import services), but changing globals in
another module is often a symptom of a design problem. There are exceptions of course,
but you should try to communicate results through devices such as function return values,
not cross-module changes. Otherwise your globals' values become dependent on the
order of arbitrarily remote assignments.
As a summary, following figure sketches the environment in which modules operate. Modules
contain variables, functions, classes, and other modules (if imported). Functions have local
variables of their own.
********