0% found this document useful (0 votes)
2 views

python2unit3

The document discusses data hiding in Python modules, emphasizing the use of naming conventions like double underscores and single underscores to manage visibility and prevent namespace pollution. It also covers how to enable future language features, the significance of the __name__ attribute for module execution, and the ability to modify the module search path. Additionally, it highlights design concepts for modules, focusing on minimizing coupling and maximizing cohesion for better code organization.

Uploaded by

shivwagh29
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

python2unit3

The document discusses data hiding in Python modules, emphasizing the use of naming conventions like double underscores and single underscores to manage visibility and prevent namespace pollution. It also covers how to enable future language features, the significance of the __name__ attribute for module execution, and the ability to modify the module search path. Additionally, it highlights design concepts for modules, focusing on minimizing coupling and maximizing cohesion for better code organization.

Uploaded by

shivwagh29
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 5

Python Programming – II

UNIT-III- Data Hiding in Modules


Data Hiding in Python
Python is the most popular programming language as it applies in every technical domain and
has a straightforward syntax and vast libraries. In the official Python documentation, Data hiding
isolates the client from a part of program implementation. Some of the essential members must
be hidden from the user. Programs or modules only reflected how we could use them, but users
cannot be familiar with how the application works. Thus it provides security and avoiding
dependency as well.

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.

Minimizing from* damage: _X and __all__


As a special case, prefixing names with a single underscore (e.g., _X) prevents them from being
copied out when a client imports with a from* statement. This really is intended only to
minimize namespace pollution; since from* copies out all names, you may get more than you
bargained for (including names that overwrite names in the importer). But underscores aren't
"private" declarations: you can still see and change such names with other import forms such as
the import statement.

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:

__all__ = ["Error", "encode", "decode"] # Export these only.


When this feature is used, the from* statement will only copy out those names listed in
the __all__ list. In effect, this is the converse of the _X convention: __all__ contains names to be
copied, but _X identifies names to not be copied. Python looks for an __all__ list in the module
first; if one is not defined, from* copies all names without a single leading underscore.
The __all__ list also only has meaning to the from* statement form, and is not a privacy
declaration. Module writers can use either trick, to implement modules that are well-behaved
when used with from*.

Enabling Future Language Features


Changes to the language that may potentially break existing code in the future are introduced
gradually. Initially, they appear as optional extensions, which are disabled by default. To turn on
such extensions, use a special import statement of this form:

from __future__ import featurename

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.

Mixed Usage Modes: __name__ and __main__

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:

% python >>> import runme >>> runme.tester( ) It's Christmas in Heaven...


But the module also includes code at the bottom that is set up to call the function when this file is
run as a program:

% python runme.py It's Christmas in Heaven...


Perhaps the most common place you'll see the __name__ test applied is for self-test code: you
can package code that tests a module's exports in the module itself, by wrapping it in
a __name__ test at the bottom.
Another common role for the __name__ trick, is for writing files whose functionalty can be used
as both a command-line utility, and a tool library. For instance, suppose you write a file finder
script in Python; you can get more mileage out of your code, if you package your code in
functions, and add a __name__ test in the file to automatically call those functions when the file
is run standalone. That way, the script's code becomes reusable in other programs.

Changing the Module Search Path:


The module search path is a list of directories initialized from environment
variable PYTHONPATH, and possibly .pth path files. What we haven't shown you until now is
how a Python program can actually change the search path, by changing a built-in list
called sys.path (the path attribute in the built-in sys module). sys.path is initialized on startup, but
thereafter, you can delete, append, and reset its components however you like:

>>> import sys >>> sys.path ['', 'D:\\PP2ECD-Partial\\Examples', 'C:\\Python22', ...more


deleted...] >>> sys.path = [r'd:\temp'] # Change module search path >>>
sys.path.append('c:\\lp2e\\examples') # for this process only. >>> sys.path ['d:\\temp',
'c:\\lp2e\\examples'] >>> import string Traceback (most recent call last): File "<stdin>", line 1,
in ? ImportError: No module named string

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.

The import as Extension


Both the import and from statements have been extended to allow a module to be given a
different name in your script:

import longmodulename as name


is equivalent to:

import longmodulename name = longmodulename del longmodulename # Don't keep


original name.
After the import, you can (and in fact must) use the name after the as to refer to the module. This
works in a from statement too:

from module import longname as name


to assign the name from the file to a different name in your script. 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.
Module Design Concepts
Like functions, modules present design tradeoffs: deciding which functions go in which module,
module communication mechanisms, and so on. Here are a few general ideas that will become
clearer when you start writing bigger Python systems:

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.

Figure Module environment

********

You might also like