For now, we have typed all instructions in the interpreter. For longer sets of instructions we need to change track and write the code in text files (using a text editor), that we will call either scripts or modules. Use your favorite text editor (provided it offers syntax highlighting for Python), or the editor that comes with the Scientific Python Suite you may be using.
Tip Let us first write a script, that is a file with a sequence of instructions that are executed each time the script is called. Instructions may be e.g. copied-and-pasted from the interpreter (but take care to respect indentation rules!). The extension for Python files is .py. Write or copy-and-paste the following lines in a file called test.py message = "Hello how are you?" for word in message.split(): print(word)
Tip Let us now execute the script interactively, that is inside the Ipython interpreter. This is maybe the most common use of scripts in scientific computing.
Note in Ipython, the syntax to execute a script is %run script.py. For example, In [1]: %run test.py Hello how are you? In [2]: message Out[2]: 'Hello how are you?' The script has been executed. Moreover the variables defined in the script (such as message) are now available inside the interpreter’s namespace.
Tip Other interpreters also offer the possibility to execute scripts (e.g., execfile in the plain Python interpreter, etc.). It is also possible In order to execute this script as a standalone program, by executing the script inside a shell terminal (Linux/Mac console or cmd Windows console). For example, if we are in the same directory as the test.py file, we can execute this in a console: $ python test.py Hello how are you?
Tip Standalone scripts may also take command-line arguments In file.py: import sys print(sys.argv) $ python file.py test arguments ['file.py', 'test', 'arguments']
Warning Don’t implement option parsing yourself. Use a dedicated module such as argparse.
In [1]: import os In [2]: os Out[2]: <module 'os' from '/usr/lib/python2.6/os.pyc'> In [3]: os.listdir('.') Out[3]: ['conf.py', 'basic_types.rst', 'control_flow.rst', 'functions.rst', 'python_language.rst', 'reusing.rst', 'file_io.rst', 'exceptions.rst', 'workflow.rst', 'index.rst'] And also: In [4]: from os import listdir Importing shorthands: In [5]: import numpy as np
Warning This is called the star import and please, Do not use it
Tip Modules are thus a good way to organize code in a hierarchical way. Actually, all the scientific computing tools we are going to use are modules: >>> import numpy as np # data arrays >>> np.linspace(0, 10, 6) array([ 0., 2., 4., 6., 8., 10.]) >>> import scipy # scientific computing
Tip If we want to write larger and better organized programs (compared to simple scripts), where some objects are defined, (variables, functions, classes) and that we want to reuse several times, we have to create our own modules. Let us create a module demo contained in the file demo.py:
Tip In this file, we defined two functions print_a and print_b. Suppose we want to call the print_a function from the interpreter. We could execute the file as a script, but since we just want to have access to the function print_a, we are rather going to import it as a module. The syntax is as follows. In [1]: import demo In [2]: demo.print_a() a In [3]: demo.print_b() b Importing the module gives access to its objects, using the module.object syntax. Don’t forget to put the module’s name before the object’s name, otherwise Python won’t recognize the instruction. Introspection In [4]: demo? Type: module Base Class: <type 'module'> String Form: <module 'demo' from 'demo.py'> Namespace: Interactive File: /home/varoquau/Projects/Python_talks/scipy_2009_tutorial/source/demo.py Docstring: A demo module. In [5]: who demo In [6]: whos Variable Type Data/Info ------------------------------ demo module <module 'demo' from 'demo.py'> In [7]: dir(demo) Out[7]: ['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'c', 'd', 'print_a', 'print_b'] In [8]: demo.<TAB> demo.c demo.print_a demo.py demo.d demo.print_b demo.pyc Importing objects from modules into the main namespace In [9]: from demo import print_a, print_b In [10]: whos Variable Type Data/Info -------------------------------- demo module <module 'demo' from 'demo.py'> print_a function <function print_a at 0xb7421534> print_b function <function print_b at 0xb74214c4> In [11]: print_a() a
Warning Module caching
Solution: In Python3 instead reload is not builtin, so you have to import the importlib module first and then do:
Tip Sometimes we want code to be executed when a module is run directly, but not when it is imported by another module. if __name__ == '__main__' allows us to check whether the module is being run directly. File demo2.py:
Importing it: In [11]: import demo2 b In [12]: import demo2 Running it:
Note Rule of thumb
When the import mymodule statement is executed, the module mymodule is searched in a given list of directories. This list includes a list of installation-dependent default path (e.g., /usr/lib/python) as well as the list of directories specified by the environment variable PYTHONPATH. The list of directories searched by Python is given by the sys.path variable In [1]: import sys In [2]: sys.path Out[2]: ['', '/home/varoquau/.local/bin', '/usr/lib/python2.7', '/home/varoquau/.local/lib/python2.7/site-packages', '/usr/lib/python2.7/dist-packages', '/usr/local/lib/python2.7/dist-packages', ...] Modules must be located in the search path, therefore you can:
A directory that contains many modules is called a package. A package is a module with submodules (which can have submodules themselves, etc.). A special file called __init__.py (which may be empty) tells Python that the directory is a Python package, from which modules can be imported. $ ls cluster/ io/ README.txt@ stsci/ __config__.py@ LATEST.txt@ setup.py@ __svn_version__.py@ __config__.pyc lib/ setup.pyc __svn_version__.pyc constants/ linalg/ setupscons.py@ THANKS.txt@ fftpack/ linsolve/ setupscons.pyc TOCHANGE.txt@ __init__.py@ maxentropy/ signal/ version.py@ __init__.pyc misc/ sparse/ version.pyc INSTALL.txt@ ndimage/ spatial/ weave/ integrate/ odr/ special/ interpolate/ optimize/ stats/ $ cd ndimage $ ls doccer.py@ fourier.pyc interpolation.py@ morphology.pyc setup.pyc doccer.pyc info.py@ interpolation.pyc _nd_image.so setupscons.py@ filters.py@ info.pyc measurements.py@ _ni_support.py@ setupscons.pyc filters.pyc __init__.py@ measurements.pyc _ni_support.pyc tests/ fourier.py@ __init__.pyc morphology.py@ setup.py@ From Ipython: In [1]: import scipy In [2]: scipy.__file__ Out[2]: '/usr/lib/python2.6/dist-packages/scipy/__init__.pyc' In [3]: import scipy.version In [4]: scipy.version.version Out[4]: '0.7.0' In [5]: import scipy.ndimage.morphology In [6]: from scipy.ndimage import morphology In [17]: morphology.binary_dilation? Type: function Base Class: <type 'function'> String Form: <function binary_dilation at 0x9bedd84> Namespace: Interactive File: /usr/lib/python2.6/dist-packages/scipy/ndimage/morphology.py Definition: morphology.binary_dilation(input, structure=None, iterations=1, mask=None, output=None, border_value=0, origin=0, brute_force=False) Docstring: Multi-dimensional binary dilation with the given structure. An output array can optionally be provided. The origin parameter controls the placement of the filter. If no structuring element is provided an element is generated with a squared connectivity equal to one. The dilation operation is repeated iterations times. If iterations is less than 1, the dilation is repeated until the result does not change anymore. If a mask is given, only those elements with a true value at the corresponding mask element are modified at each iteration.
Quick read If you want to do a first quick pass through the Scipy lectures to learn the ecosystem, you can directly skip to the next chapter: NumPy: creating and manipulating numerical data. The remainder of this chapter is not necessary to follow the rest of the intro part. But be sure to come back and finish this chapter later. |