190 likes | 396 Views
Chapter 15-18 Modules. CSC1310 Fall 2009. Modules. Modules are the highest level program organization unit, usually correspond to source files and serve as libraries of tools. Each file is a module and modules import other modules to use the name they define.
E N D
Chapter 15-18Modules CSC1310 Fall 2009
Modules • Modules are the highest level program organization unit, usually correspond to source files and serve as libraries of tools. • Each file is a module and modules import other modules to use the name they define. • import: lets a client fetch a module as a whole • from: allows to fetch particular names from module • reload: provides a way to reload code without stopping Python.
Why Use Modules? 1. Code reuse Code in module is persistent: can be reloaded and run as many times as needed. 2. System namespace partitioning Everything “lives” in a module: code and objects are always implicitly enclosed by a module. 3. Implementing shared services or data Components shared across a system
Module Creation • Easy to create: files that are created with text editor. • Top-level assignments create module attributes. • You can call modules anything (except keywords), but module filenames should end in .py extension
Modules Usage: import • Clients can use the module file by running import statement >>>import math # file to be loaded >>>print math.pi # variable in the script >>>print math.sqrt(4), math.log(10) • import gives the whole module object • Module name is necessary to fetch (use, call) its attributes
Modules Usage: from • Clients can use the module file by running from statement >>>from math import pi, sqrt >>>print pi,sqrt(6) • from copies specified names out of the module. • The copied names are used directly withoutgoing through module.
Modules Usage: from * • Special form of from statement (with *) gives copies of all names in the referenced module. >>>from fib import * >>>print fibTopN(6), fib(6), list, add() • The copied names are used directly without going through module.
Import Runs Only Once • Import is expensive operation, so it happens only on first import of from. • Later import operations fetch an already-loaded module object (code is not rerun!)
import, from are Assignments • import assigns an entire module object to a single name. • from assigns one or more names to objects of the same name in another module. • Name copied with from becomes a reference to a shared object (fetched mutable object can be changed). >>>from fib import list, size >>>list[0]=“changed!”, size=12 • Cross-File Name Changes: >>>import fib >>>fib.size=23 #earlier “size” was 12 which is still 12
Rename • Both import, from were extended to allow a module to be given a different name. >>>import fib as f >>>print f.multiple() >>>from fib import multiple as mult >>>print mult([1,2,3]) • Short synonyms for long names. • Avoiding name clashes.
Reloading Modules • reload function forces already loaded module code to be reloaded and rerun. • Assignments in the new code change the existing module object in-place. • It allows to change parts of running programs without stopping. • reload is passed an existing module object, not a name. >>>import fib …. >>>reload(fib)
reload Basics • reload runs a module file’s new code in the module’s current namespace. • Impacts all files that use import. • Impacts only futurefrom clients only, since previous from clients got a copy not a reference to an object.
reload Example • In interactive shell: >>>import fib >>>print fib.multiple() • Change fib.py: list2=[‘a’,’b’,’c’,’d’,’e’] def multiple(l=list2): return [l[x]*x for x in range(len(l))] • In interactive shell: >>>reload(fib) >>>print fib.multiple()
reload Example • In interactive shell (before changes): >>>from math import sqrt,pi >>>print pi • You change pi • >>>pi = 3.0 • In interactive shell you try: >>>reload(math) # doesn’t work, from assigned name pi and sqrt, not name math >>>import(math) >>>reload(math) >>>print pi # from makes copy of function! • So, you need either: • Call it math.pi OR Rerun the from (from math import pi)
Data Hiding in Modules • Data hiding in Python is a convention, not a syntax. • You can not prevent changes from outside. • Single leading underscore in name (_name) prevents variable from being copied with from *. • Hiding effect can be achieved by assigning a list of variable name string to the global variable __all__. If __all__ is defined, from * copies only variable mentioned there; otherwise, it copies all variables without a single leading underscore. _x=3 __all__=["add","fib","list"]
Mixed Usage Modes • Each module has a built-in attribute __name__: • “__main__” if file is being run as a top-level program • module’s name if file is being imported • Module can test its own __name__ to determine whether it’s being run or imported(different behavior, testing) • In runme.py import fib def imported(): print “It is imported” if __name__==“__main__”: print fib.fib(4)
Changing the Module Search Path • Program can change the search path by changing a built-in list called sys.path • sys.path is initialized on startup, but then you can delete, append, and reset its components: >>>import sys >>>sys.path.append(“c:\\Temp”) • Be careful: if you delete a critical directory from the path, you may lose access to critical utilities. • Your settings are not retained after Python exits.
Module Design Concepts • You’re always in a module in Python. Indeed, code typed in interactive prompt really goes to built-in module __main__ • Minimize module coupling: global variables. • Maximize module cohesion: unified purpose. • Modules should rarely change other modules’ variables (function return values)
Importing Modules Dynamically >>>import ”string” >>>x=“string” >>>import x • If you get name to import dynamically, you need to construct an import statement as a string of Python code and pass it to exec. >>>name=“string” >>>exec “import”+name • exec statement compiles a string of code and passes it to Python interpreter to be executed. • __import__ loads from a string and returns the module object. It works quicker than exec. >>>string=__import__(name)