Why does way_1() obtain the correct list but way_2() gets an empty list?

Bruno Desthuilliers bruno.42.desthuilliers at websiteburo.invalid
Thu Feb 12 06:54:55 EST 2009


WP a écrit :
> Hello group! This is probably a silly newbie mistake but consider the 
> following program:
> 
> import libsbml
> 
> def getSBMLModel(biomodel_path):
>     reader = libsbml.SBMLReader()
> 
>     sbml_doc = reader.readSBML(biomodel_path)
>     sbml_model = None
> 
>     if sbml_doc.getNumErrors() > 0:
>         print 'I couldn\'t read the file %s!' % biomodel_path

This should go to stderr. stdout is for normal program outputs.

>         return None

Also, Python has exception handling, which is usually a better solution 
than returning None or whatever.

>     else:

since you returned in the other branch, this else is useless

>         sbml_model = sbml_doc.getModel()
> 
>     return sbml_doc.getModel() # None if file couldn't be opened

You're calling  sbml_doc.getModel() a first time, binding the returned 
value to name sbml_model, then you're calling it a second time to return it.

A first fix:

import sys

def getSBMLModel(biomodel_path):
     reader = libsbml.SBMLReader()
     sbml_doc = reader.readSBML(biomodel_path)
     if sbml_doc.getNumErrors() > 0:
          # XXX : there's perhaps a better error message
          #       to get from sbml_doc ?
          print >> sys.stderr,  "I couldn't read the file %s!"\
                                 % biomodel_path
          return None

     return sbml_doc.getModel()


> 
> def way_1(biomodel_path):
>     reader = libsbml.SBMLReader()
>     sbml_doc = reader.readSBML(biomodel_path)
>     sbml_model = sbml_doc.getModel()
> 
>     if sbml_model == None:

Better to use the identity test here - None is garanteed to be a singleton:

       if sbml_model is None:

>         return
> 
>     l = sbml_model.getListOfSpecies()
>     print 'In way_1(): Got list %s with the length %i' % (l, len(l))
> 
> 
> def way_2(biomodel_path):
>     sbml_model = getSBMLModel(biomodel_path)
> 
>     if sbml_model == None:
>         return
> 
>     l = sbml_model.getListOfSpecies()
>     print 'In way_2(): Got list %s with the length %i' % (l, len(l))
> 
> 
> file = '../BIOMD0000000003.xml'

This shadows the builtin 'file' symbol. Better to use another name.

> # Changing the order of these two calls doesn't help, only way_1() works.
> way_1(file)
> way_2(file)
> 
> When run, the output is:
> In way_1(): Got list <libsbml.ListOfSpecies; proxy of <Swig Object of 
> type 'ListOfSpecies *' at 0x291c8bc> > with the length 3
> In way_2(): Got list <libsbml.ListOfSpecies; proxy of <Swig Object of 
> type 'ListOfSpecies *' at 0x27fb57c> > with the length 0
> 
> I don't get it way the species list obtained in way_2() is empty?

The only explanation I can imagine here would be that a second call to 
sbml_doc.getModel() doesn't return the same thing as the first... 
(remember, there are two calls in your getSBMLModel() function).

My 2 cents...



More information about the Python-list mailing list