[Tutor] Troubles with Python modules

Danny Yoo dyoo at hkn.eecs.berkeley.edu
Tue May 17 18:58:10 CEST 2005



On Tue, 17 May 2005, Alberto Troiano wrote:

> I'm working on Python 2.2 over Linux REd Hat 9.0 and here is the code I
> have

[code cut]

> First I'd like to know if this code can be shorter or more efficient (if
> you have the time)

Yes.  But let's look at the errors first.



> Second the error is the following:
>
> Traceback (most recent call last):
>   File "/root/cotascamon.py", line 4, in ?
>     import datetime
> ImportError: No module named datetime
>
> I think this module is in Python 2.3. What can I do??????

I'll assume for the moment that you are using your root account.  Are you
sure that your root account is using Python 2.3?  It may be possible that
the root account has a slightly more restricive PATH than normal user
accounts, and that you might be picking up '/usr/bin/python'.



> Then I have installed Python 2.3.4 in the same Linux but I can't use it
> because it doesn't recognze the module MySQLdb
>
> Here is the error
>
> Traceback (most recent call last):
>   File "/root/cotascamon.py", line 3, in ?
>     import MySQLdb
>   File "/usr/local/lib/python2.3/site-packages/MySQLdb/__init__.py", line
> 27, in ?
>     import _mysql
> ImportError: No module named _mysql


Different releases of Python will not automatically migrate the old
third-party modules.  You'll need to reinstall MySQLdb for Python 2.3.
MySQLdb can be found here:

    http://sourceforge.net/projects/mysql-python




Let's look at some of the code.


>     def consulta(self,query,args=None):
>         try:
>             self.cursor=self.db.cursor()
>             self.sql=self.cursor.execute(query,args)
>         except:
>             self.cerrar()
>         else:
>             self.cerrar()

The consulta() function tries to make sure that the cerrar()  method is
called, no matter what.  In this case, try/finally may do what you want:

######
try:
    ...
finally:
    self.cerrar()
######



> def getpath():
>     global ruta
>     global user
>     global cam
>     try:
>         i=0
>         for arg in sys.argv:
>             if i==1:
>                 ruta+=arg
>             elif i==2:
>                 user=arg
>             elif i==3:
>                 cam=arg
>             else:
>                 pass
>             i+=1
>     except:
>         f=open("cotascamonerrors.log","a+")
>         f.write("ERROR ------ No se pudo encontrar el path "+ruta+".
> Contacte al administrador.")
>         f.close()

This looks like it's trying to do argument parsing, storing state in
global variables.  You may want to see if you can avoid the globals, and
instead just return those three values back to the caller.

My nervousness with the globals comes from the requirement that getpath()
has to assume that 'ruta' already has some sort of value already.  So
there's already a dependency that can be more clearly documented by making
getpath() take in an initial base path argument:

######
def getpath(base_path):
    ...
    return (ruta, user, cam)
######


But the block above also feels a little awkward because it assumes that
any exception that occurs has to be a path problem.  That might not
necessarily be the case.  I'd strongly recommend letting the exception
speak for itself.  traceback.print_exc() can help:

    http://www.python.org/doc/lib/module-traceback.html

######
try:
    ....
except:
    f = open("cotascamonerrors.log", "a+")
    traceback.print_exc(file=f)
    f.close()
######


Up to this point, though, things are pretty ok, with the nice helper
functions with clear roles.  The large block near the bottom, though,
needs work.  I'd recommend applying the same helper-function breakup to
make the code's intent clearer.


For example, here's SQL code that's repeated, a.  It should be broken out:

>             try:
>                 os.system("cp webcam.jpg grabacion/cam"+grupo+".jpg")
>                 query="INSERT INTO imagen values (%s,%s,%s,NOW(),NOW(),%s)
> where CodigoCamara=%s and Usuario=%s"
>                 grupo1=datetime.datetime.today().strftime("%Y%m%d%H%M")
>                 ruta1=ruta+"/grabacion/cam"+grupo+".jpg"
>                 args(user,cam,ruta1,grupo1)
>                 cur.consulta(query,args)
>             except:
>                 pass


Again, try not to obscure exceptions.  If something bad happens, you
really want the exception to tell you what happened: it is not fun to
debug something when the error message is insufficiently helpful.  Change
the except block to log the error message.



I do not understand what's happening with args() above:

>                 args(user,cam,ruta1,grupo1)

Do you mean:

                  args = (user,cam,ruta1,grupo1)

instead?


Hope this helps!



More information about the Tutor mailing list