-1

I have a script that needs to use a slightly unusual try structure, of the general form:

   try:
      # Try to get object 1 (may or may not exist)
   except:
      # Try to get object 2 (may or may not exist)
   else:
      try:
         # Try to append object 2 (which may not exist) to object 1, which has been retrieved already
   
   # Do stuff with the retrieved object/composite object

I always get an 'unexpected indent' error at the last section (where I try to do stuff with my retrieved object), unless I put a dummy finally block in:

   try:
      # Try to get object 1 (may or may not exist)
   except:
      # Try to get object 2 (may or may not exist)
   else:
      try:
         # Try to append object 2 (which may not exist) to object 1, which has been retrieved already
      finally:
         dummy = 1

   # Do stuff with the retrieved object/composite object

There is zero point to setting dummy = 1, other than that it seems to work. Is this expected behaviour? Is it possible to use such a nest (or alternative syntax) without resorting to dummy lines of code!?

Finally, in one place where I do this, there is an additional line of code that is only required if the second 'try' statement executes without exception, but there seems to be no way of making this work elegantly with an 'else' clause on the inner/second 'try'. The following gives an 'invalid syntax' error on the second 'else' line:

   try:
      # Try to get object 1 (may or may not exist)
   except:
      # Try to get object 2 (may or may not exist)
   else:
      try:
         # Try to append object 2 (which may not exist) to object 1, which has been retrieved already
      else:
         # Do action only required on composite object
      finally:
         dummy = 1

   # Do stuff with the retrieved object/composite object
RobBaker
  • 137
  • 11
  • 1
    Every `try` block requires an `except` or `finally`! Without those, `try` makes no sense. Just `try..else` is the same as leaving the `try` out entirely. – deceze Oct 19 '20 at 13:15
  • what do you expect to happen with your initial only `try:`? – rioV8 Oct 19 '20 at 13:16
  • The whole thing seems… weird. Only if retrieving object 1 fails do you attempt to get object 2, but only if object 1 was retrieved successfully do you try to append object 2 to it. That just doesn't make a whole lot of logical sense, unless we're missing some detail here. – deceze Oct 19 '20 at 13:19

2 Answers2

2

You are overcomplicating things. You should use try when dealing with the possibility of errors. For logic, it's better to use an if statement.

Just do:

try:
   obj1 = ... # get first obj
except: # obj doesn't exist
   obj1 = None

try:
   obj2 = ... # get second obj
except: # obj doesn't exist
   obj2 = None

if obj1 and obj2: # if obj1 exists and obj2 exists
   obj1.append(obj2)


Maciej M
  • 786
  • 6
  • 17
  • 1
    You're totally right, of course - I had been narrowly trying to port functioning VBA code, but actually the structure you propose is much better. The underlying problem does make sense, for the information of those who were questioning the premise: I am retrieving engineering model data for a stream of material - I essentially want the oily or the aqueous liquid phase, or an aggregate of both, if they both exist (from a COM object). Thanks Maciej M! – RobBaker Oct 19 '20 at 13:56
1

You always need to provide a finally or except when doing a try. Think about what you would want to happen if object 2 does not exist when appending to object 1. If you want to do something to handle this, put it in the except. If not, then you shouldn't be using a try/except for this. To check if variables exist before doing anything with them, you could use an if statement. If statements do not require an else, so if the condition is not met, nothing will happen and it will not throw an error. e.g.

if obj1:
    # object 1 exists
    if obj2:
        # object 2 exists
        obj1.append(obj2)