PageRenderTime 57ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/notes/python_scripts_modules.rst

https://bitbucket.org/andybaoxv/uwhpsc
ReStructuredText | 407 lines | 292 code | 115 blank | 0 comment | 0 complexity | 9547cde5001f5e6ed17fcc65ad97c219 MD5 | raw file
  1. .. _python_scripts_modules:
  2. =============================================================
  3. Python scripts and modules
  4. =============================================================
  5. A Python script is a collection of commands in a file designed to be
  6. executed like a program. The file can of course contain functions and
  7. import various modules, but the idea is that it will be run or executed
  8. from the command line or from within a Python interactive shell to perform a
  9. specific task. Often a script first contains a set of function definitions
  10. and then has the *main program* that might call the functions.
  11. Consider this script, found in $UWHPSC/python/script1.py:
  12. **script1.py**
  13. .. literalinclude:: ../codes/python/script1.py
  14. :language: python
  15. :linenos:
  16. The *main program* starts with the print statement.
  17. There are several ways to run a script contained in a file.
  18. At the Unix prompt::
  19. $ python script1.py
  20. x f(x)
  21. 0.000 1.000
  22. 2.000 5.000
  23. 4.000 17.000
  24. From within Python::
  25. >>> execfile("script1.py")
  26. [same output as above]
  27. From within IPython, using either `execfile` as above, or `run`::
  28. In [48]: run script1.py
  29. [same output as above]
  30. Or, you can `import` the file as a module (see :ref:`importing_modules`
  31. below for more about this)::
  32. >>> import script1
  33. x f(x)
  34. 0.000 1.000
  35. 2.000 5.000
  36. 4.000 17.000
  37. Note that this also gives the same output. Whenever a module is imported,
  38. any statements that are in the main body of the module are executed when it
  39. is imported. In addition, any variables or functions defined in the file
  40. are available as attributes of the module, e.g., ::
  41. >>> script1.f(4)
  42. 17.0
  43. >>> script1.np
  44. <module 'numpy' from
  45. '/Library/Python/2.5/site-packages/numpy-1.4.0.dev7064-py2.5-macosx-10.3-fat.egg/numpy/__init__.pyc'>
  46. Note there are some differences between executing the script and importing
  47. it. When it is executed as a script,
  48. it is as if the commands were typed at the command line. Hence::
  49. >>> execfile('script1.py')
  50. x f(x)
  51. 0.000 1.000
  52. 2.000 5.000
  53. 4.000 17.000
  54. >>> f
  55. <function f at 0x1c0430>
  56. >>> np
  57. <module 'numpy' from
  58. '/Library/Python/2.5/site-packages/numpy-1.4.0.dev7064-py2.5-macosx-10.3-fat.egg/numpy/__init__.pyc'>
  59. In this case `f` and `np` are in the namespace of the interactive session as
  60. if we had defined them at the prompt.
  61. .. _python_name_main:
  62. Writing scripts for ease of importing
  63. -------------------------------------
  64. The script used above as an example contains a function `f(x)` that we might
  65. want to be able to import without necessarily running the *main program*.
  66. This can be arranged by modifying the script as follows:
  67. **script2.py**
  68. .. literalinclude:: ../codes/python/script2.py
  69. :language: python
  70. :linenos:
  71. When a file is imported or executed, an attribute `__name__` is
  72. automatically set, and has the value `__main__` only if the file is executed
  73. as a script, not if it is imported as a module. So we see the following
  74. behavior::
  75. $ python script2.py
  76. x f(x)
  77. 0.000 1.000
  78. 2.000 5.000
  79. 4.000 17.000
  80. as with `script1.py`, but::
  81. >>> import script2 # does not print table
  82. >>> script2.__name__
  83. 'script2' # not '__main__'
  84. >>> script2.f(4)
  85. 17.0
  86. >>> script2.print_table()
  87. x f(x)
  88. 0.000 1.000
  89. 2.000 5.000
  90. 4.000 17.000
  91. .. _python_reload:
  92. Reloading modules
  93. -----------------
  94. When you import a module, Python keeps track of the fact that it is imported
  95. and if it encounters another statement to import the same module will not
  96. bother to do so again (the list of modules already import is in
  97. `sys.modules`). This is convenient since loading a module can be
  98. time consuming. So if you're debugging a script using `execfile` or `run`
  99. from an IPython shell, each time you change it and then re-execute it will
  100. not reload `numpy`, for example.
  101. Sometimes, however, you want to force reloading of a module, in particular
  102. if it has changed (e.g. when we are debugging it).
  103. Suppose, for example, that we modify `script2.py` so
  104. that the quadratic function is changed from `y = x**2 + 1 ` to
  105. `y = x**2 + 10`.
  106. If we make this change and then try the following (in the same Python
  107. session as above, where `script2` was already imported as a module)::
  108. >>> import script2
  109. >>> script2.print_table()
  110. x f(x)
  111. 0.000 1.000
  112. 2.000 5.000
  113. 4.000 17.000
  114. we get the same results as above, even though we changed `script2.py`.
  115. We have to use the `reload` command to see the change we want::
  116. >>> reload(script2)
  117. <module 'script2' from 'script2.py'>
  118. >>> script2.print_table()
  119. x f(x)
  120. 0.000 10.000
  121. 2.000 14.000
  122. 4.000 26.000
  123. .. _python_argv:
  124. Command line arguments
  125. ----------------------
  126. We might want to make this script a bit fancier by adding an optional argument
  127. to the `print_table` function to print a different number of points, rather
  128. than the 3 points shown above.
  129. The next version has this change, and also has a modified version of the
  130. main program that allows the user to specify this value `n` as a command
  131. line argument:
  132. **script3.py**
  133. .. literalinclude:: ../codes/python/script3.py
  134. :language: python
  135. :linenos:
  136. Note that:
  137. * The function `sys.argv` from the `sys` module returns the arguments that
  138. were present if the script is executed from the command line. It is a
  139. list of strings, with `sys.argv[0]` being the name of the script itself,
  140. `sys.argv[1]` being the next thing on the line, etc. (if there were more
  141. than one command line argument, separated by spaces).
  142. * We use `int(sys.argv[1])` to convert the argument, if present, from a
  143. string to an integer.
  144. * We put this conversion in a try-except block in case the user gives an
  145. invalid argument.
  146. Sample output::
  147. $ python script3.py
  148. x f(x)
  149. 0.000 1.000
  150. 2.000 5.000
  151. 4.000 17.000
  152. $ python script3.py 5
  153. x f(x)
  154. 0.000 1.000
  155. 1.000 2.000
  156. 2.000 5.000
  157. 3.000 10.000
  158. 4.000 17.000
  159. $ python script3.py 5.2
  160. *** Error: expect an integer n as the argument
  161. .. _importing_modules:
  162. Importing modules
  163. -----------------
  164. When Python starts up there are a certain number of basic commands defined
  165. along with the general syntax of the language, but most useful things needed
  166. for specific purposes (such as working with webpages, or solving linear
  167. systems) are in *modules* that do not load by default. Otherwise it would
  168. take forever to start up Python, loading lots of things you don't plan to
  169. use. So when you start using Python, either interactively or at the top of
  170. a script, often the first thing you do is *import* one or more modules.
  171. A Python module is often defined simply by grouping a set of parameters and
  172. functions together in a single .py file.
  173. See :ref:`python_scripts_modules` for some examples.
  174. Two useful modules are *os* and *sys* that help you interact with the
  175. operating system and the Python system that is running. These are standard
  176. modules that should be available with any Python implementation, so you
  177. should be able to import them at the Python prompt::
  178. >>> import os, sys
  179. Each module contains many different functions and parameters which are the
  180. *methods* and *attributes* of the module. Here we will only use a couple
  181. of these. The
  182. *getcwd* method of the os module is called to return the "current working
  183. directory" (the same thing *pwd* prints in Unix), e.g.::
  184. >>> os.getcwd()
  185. /home/uwhpsc/uwhpsc/codes/python
  186. Note that this function is called with no arguments, but you need the open
  187. and close parens. If you type "os.getcwd" without these, Python will
  188. instead print what type of object this function is::
  189. >>> os.getcwd
  190. <built-in function getcwd>
  191. .. python_path:
  192. The Python Path
  193. ---------------
  194. The *sys* module has an attribute *sys.path*, a variable that is set by
  195. default to the search path for modules. Whenever you perform an *import*,
  196. this is the set of directories that Python searches through looking for a
  197. file by that name (with a .py extension). If you print this, you will see a
  198. list of strings, each one of which is the full path to some directory.
  199. Sometimes the first thing in this list is the empty string, which means "the
  200. current directory", so it looks for a module in your working directory first
  201. and if it doesn't find it, searches through the other directories in order:
  202. >>> print sys.path
  203. ['', '/usr/lib/python2.7', ....]
  204. If you try to import a module and it doesn't find a file with this name on
  205. the path, then you will get an import error::
  206. >>> import junkname
  207. Traceback (most recent call last):
  208. File "<stdin>", line 1, in <module>
  209. ImportError: No module named junkname
  210. When new Python software such as NumPy or SciPy is installed, the
  211. installation script should modify the path appropriately so it can be found.
  212. You can also add to the path if you have your own directory that you want
  213. Python to look in, e.g.::
  214. >>> sys.path.append("/home/uwhpsc/mypython")
  215. will append the directory indicated to the path. To avoid having to do this
  216. each time you start Python, you can set a Unix environment variable that
  217. is used to modify the path every time Python is started. First print out
  218. the current value of this variable::
  219. $ echo $PYTHONPATH
  220. It will probably be blank unless you've set this before or have installed
  221. software that sets this automatically.
  222. To append the above example directory to this path::
  223. $ export PYTHONPATH=$PYTHONPATH:/home/uwhpsc/mypython
  224. This appends another directory to the search path already specified (if any).
  225. You can repeat this multiple times to add more directories, or put something
  226. like::
  227. export PYTHONPATH=$PYTHONPATH:dir1:dir2:dir3
  228. in your *.bashrc* file if there are the only 3 personal
  229. directories you always want to search.
  230. Other forms of import
  231. ----------------------------------------
  232. If all we want to use from the *os* module is *getcwd*, then another option
  233. is to do::
  234. >>> from os import getcwd
  235. >>> getcwd()
  236. '/Users/rjl/uwhpsc/codes/python'
  237. In this case we only imported one method from the module, not the whole
  238. thing. Note that now *getcwd* is called by just giving the name of the
  239. method, not *module.method*. The name *getcwd* is
  240. now in our *namespace*. If we only imported *getcwd* and tried typing
  241. "os.getcwd()" we'd get an error, since it wouldn't find *os* in our
  242. namespace.
  243. You can rename things when you import them, which is sometimes useful if
  244. different modules contain different objects with the same name.
  245. For example, to compare how the `sqrt` function in the standard Python math
  246. module compares to the numpy version::
  247. >>> from math import sqrt as sqrtm
  248. >>> from numpy import sqrt as sqrtn
  249. >>> sqrtm(-1.)
  250. Traceback (most recent call last):
  251. File "<stdin>", line 1, in <module>
  252. ValueError: math domain error
  253. >>> sqrtn(-1.)
  254. nan
  255. The standard function gives an error whereas the *numpy* version returns
  256. *nan*, a special *numpy* object representing "Not a Number".
  257. You can also import a module and give it a different name locally. This is
  258. particularly useful if you import a module with a long name, but even for
  259. *numpy* many examples you'll find on the web abbreviate this as *np*
  260. (see :ref:`numerical_python`)::
  261. >>> import numpy as np
  262. >>> theta = np.linspace(0., 2*np.pi, 5)
  263. >>> theta
  264. array([ 0. , 1.57079633, 3.14159265, 4.71238898, 6.28318531])
  265. >>> np.cos(theta)
  266. array([ 1.00000000e+00, 6.12323400e-17, -1.00000000e+00, -1.83697020e-16, 1.00000000e+00])
  267. If you don't like having to type the module name repeatedly you can import
  268. just the things you need into your namespace::
  269. >>> from numpy import pi, linspace, cos
  270. >>> theta = linspace(0., 2*pi, 5)
  271. >>> theta
  272. array([ 0. , 1.57079633, 3.14159265, 4.71238898, 6.28318531])
  273. >>> cos(theta)
  274. array([ 1.00000000e+00, 6.12323400e-17, -1.00000000e+00, -1.83697020e-16, 1.00000000e+00])
  275. If you're going to be using lots of things form *numpy* you might want to
  276. import everything into your namespace::
  277. >>> from numpy import *
  278. Then *linspace*, *pi*, *cos*, and several hundred other things will be available
  279. without the prefix.
  280. When writing code it is often best to not do this, however, since then it is
  281. not clear to the reader (or even to the programmer sometimes)
  282. what methods or attributes are coming from which module if several
  283. different modules are being used. (They may define methods with the same
  284. names but that do very different things, for example.)
  285. When using IPython, it is often convenient to start it with::
  286. $ ipython --pylab
  287. This automatically imports everything from *numpy* into the namespace, and
  288. also all of the plotting tools from *matplotlib*.
  289. Further reading
  290. ----------------
  291. `Modules section of Python documentation
  292. <http://docs.python.org/2/tutorial/modules.html>`_