# modules.py # Namespaces # # Namespace is a concept used in programming languages. As we create # functions, thus function names, we may want to create the same function # name to mean different things in different contexts. For example, count # may mean counting students or beans depending on which program you are # dealing with. Rather than naming them count_student and count_bean # we may want to name them both count, but in different contexts. We create # a namespace in which names are contained. So if we have a namespace that # contains all the names that deal with students and another containing # all the names that deal with beans, then we can use the same name, e.g., # count, as long as we distinguish one from the other by using the name of # the namespace it belongs to. Namespace is used to manage names in a # programming language. After all, a program consists of a bunch of names # such as variable names, function names, etc. When there are many names, # it is easier to deal with them if we partition them into different spaces. # Python like many other languages supports this mechanism and it is # implemented by modules. # Modules # # A module is a file containing Python definitions that are intended to be # used in other Python programs. There are many Python modules that come # with the language Python as part of the standard library. We have seen # two of those already: the string module and the math module. # Let us learn how to create a module of our own now. All we need to # create a module is a Python program file with a .py extension in the # filename. For example, functions.py that I created is one such module. # # Let us create one as follows: we will create a file named seqtools.py that # contains two definitions named remove_at and insert_at. I will create it # as a separate file named seqtools.py. # # see seqtools.py # Now, that we created a module (seqtools.py), let us learn how to use it. # # Start a Python session using the shell mode, and try the following. I am # showing you an exact interaction: # # >>> from seqtools import remove_at # >>> s = "This is fun!" # >>> remove_at(s, 3) # 'Thi is fun!' # # As you can see, we are using the 'from . . . import' command to import # a specific name (remove_at) from a module (seqtools). We have imported # only one definition out of two in seqtools.py. # # In this particular situation we imported the name (remove_at) into the # current module, which is the top-level, interactive module. Once you # import it, you can use the imported name as if the name was created in # the current module that you are in. # # One bad thing is that if you already had the same name in the current # module, the old one will be lost. To avoid this situation, there is # another way of importing, which I will show you next. # # Here again I am showing you an interactive session using the shell mode # to illustrate how it is done, like this: # # >>> import seqtools # >>> s = "This is fun!" # >>> seqtools.remove_at(s, 3) # 'Thi is fun!' # # As you can see here we are importing everything from the module seqtools. # # Note that we don't say 'import seqtools.py', but rather 'import seqtools' # without the file extension (.py). Since there are two definitions in # seqtools, both are imported. If we import it this way, we MUST specify # the module name along with the name in the module if we want to use a # name in the imported module. # # We use the dot ('.') operator to separate the module name and a name in # the module, e.g., seqtools.insert_at. Suppose there was already a # definition named insert_at in the current module. Then, insert_at alone # would refer to the one in the current module, and seqtools.insert_at would # refer to the one from seqtools module. # # Note that this works because we have the file seqtools.py located in the # same folder where the current python session was started at. If the module # to be imported is located in a different folder, we would have to do a # little more work. I will explain that a little later in this file. # # Some programming languages use packages to mean modules. I may use that # term inadvertently in the future, and you will know what I mean if I do. # The "from ... import" version also has a wildcard option: We can use # 'from modulename import *' to mean import everything from the named # module, e.g., # # >>> from seqtools import * # # This would import all the names from seqtools into the current module thus # overwriting any existing names if there are names that are the same in # the current module as the ones imported from seqtools. # The dir() function is useful. . . # Once you import a module, you can use the dir function to see all the # functions defined in the module. For example, try the following: # # >>> import math # >>> dir(math) # Getting back to the case where the module that you want to import is # located elsewhere, what would we have to do if the module to be imported # is located in a different folder than the folder where the current python # session was started at? Well, if the module file is located in one of # the folders that is included in the current 'path' for the python session, # then you don't need to do anything. If not, we will have do some more # work. So, how do we find out if the folder where the module to be # imported is located is in the path or not? Try this in your current # python session: # # >>> import sys # >>> sys.path # # The value of sys.path is returned and it will show all the folders that are # included in the path. If the folder where the module is located is in the # the path, you are done. If not, we have to include that folder in the path. # Assuming that the module is located in the folder: /Users/alee/python, this # is what we would do: # # >>> import os # >>> os.path.join ## Just to see if join is available # # >>> sys.path ## Tried on a Mac machine (Unix) # ## see init.py for Windows version # ['', '/Library/Frameworks/Python.framework/Versions/5.1.1/bin', '/Library/Frameworks/Python.framework/Versions/5.1.1/lib/python25.zip', '/Library/Frameworks/Python.framework/Versions/5.1.1/lib/python2.5', '/Library/Frameworks/Python.framework/Versions/5.1.1/lib/python2.5/plat-darwin', '/Library/Frameworks/Python.framework/Versions/5.1.1/lib/python2.5/plat-mac', '/Library/Frameworks/Python.framework/Versions/5.1.1/lib/python2.5/plat-mac/lib-scriptpackages', '/Library/Frameworks/Python.framework/Versions/5.1.1/lib/python2.5/lib-tk', '/Library/Frameworks/Python.framework/Versions/5.1.1/lib/python2.5/lib-dynload', '/Library/Frameworks/Python.framework/Versions/5.1.1/lib/python2.5/site-packages', '/Library/Frameworks/Python.framework/Versions/5.1.1/lib/python2.5/site-packages/PIL', '/Library/Frameworks/Python.framework/Versions/5.1.1/lib/python2.5/site-packages/IPython/Extensions', u'/Users/alee/.ipython'] # >>> sys.path.append(os.path.join("/Users", "alee", "python")) # >>> sys.path # ['', '/Library/Frameworks/Python.framework/Versions/5.1.1/bin', '/Library/Frameworks/Python.framework/Versions/5.1.1/lib/python25.zip', '/Library/Frameworks/Python.framework/Versions/5.1.1/lib/python2.5', '/Library/Frameworks/Python.framework/Versions/5.1.1/lib/python2.5/plat-darwin', '/Library/Frameworks/Python.framework/Versions/5.1.1/lib/python2.5/plat-mac', '/Library/Frameworks/Python.framework/Versions/5.1.1/lib/python2.5/plat-mac/lib-scriptpackages', '/Library/Frameworks/Python.framework/Versions/5.1.1/lib/python2.5/lib-tk', '/Library/Frameworks/Python.framework/Versions/5.1.1/lib/python2.5/lib-dynload', '/Library/Frameworks/Python.framework/Versions/5.1.1/lib/python2.5/site-packages', '/Library/Frameworks/Python.framework/Versions/5.1.1/lib/python2.5/site-packages/PIL', '/Library/Frameworks/Python.framework/Versions/5.1.1/lib/python2.5/site-packages/IPython/Extensions', u'/Users/alee/.ipython', '/Users/alee/python'] # Now, you can see that /Users/alee/python is included in the path, and you # should be able to import a module located in that folder, as you can see # below: # # >>> import seqtools # >>> s = "Thisisfun..." # >>> seqtools.remove_at(s, 3) # 'Thiisfun...' # # Note that remove_at(s, 3) without seqtools. would not work. However, if you # imported it using 'from seqtools import *' then remove_at(s, 3) alone would # work. # # I can encapsulate all this stuff that I just did to add something into the # path in a file called init.py and you may use it every time you want to do # something like this. See init.py to see what I did. With init.py # available, next time just do the following right after you start a new # python session: # # >>> execfile("init.py") # # and then continue with whatever you wanted to do in your current python # session. Remember to edit init.py so that it will work with your computer. # The one you get from me would work on my machine, but you need to customize # it to make it work with yours. Read init.py before you use it. # There are a few more subtleties with modules and you may refer to a section # in [Downey] on modules if you want to learn more about them.