Are nested try/except blocks in python a good programming practice?

后端 未结 11 2032
情歌与酒
情歌与酒 2020-12-07 08:33

I\'m writing my own container, which needs to give access to a dictionary inside by attribute calls. The typical use of the container would be like this:

dic         


        
相关标签:
11条回答
  • 2020-12-07 09:01

    Your first example is perfectly fine. Even the official Python docs recommend this style known as EAFP.

    Personally, I prefer to avoid nesting when it's not necessary:

    def __getattribute__(self, item):
        try:
            return object.__getattribute__(item)
        except AttributeError:
            pass  # fallback to dict
        try:
            return self.dict[item]
        except KeyError:
            raise AttributeError("The object doesn't have such attribute") from None
    

    PS. has_key() has been deprecated for a long time in Python 2. Use item in self.dict instead.

    0 讨论(0)
  • 2020-12-07 09:03

    If try-except-finally is nested inside finally block, the result from "child" finally is preserved. I have not found official expaination yet, but the following code snippet shows this behavior in Python 3.6.

    def f2():
        try:
            a = 4
            raise SyntaxError
        except SyntaxError as se:
            print('log SE')
            raise se from None
        finally:
            try:
                raise ValueError
            except ValueError as ve:
                a = 5
                print('log VE')
                raise ve from None
            finally:
                return 6       
            return a
    
    In [1]: f2()
    log SE
    log VE
    Out[2]: 6
    
    0 讨论(0)
  • 2020-12-07 09:07

    In my opinion this would be the most Pythonic way to handle it, although and because it makes your question moot. Note that this defines__getattr__()instead of__getattribute__() because doing so means it only has to deal with the "special" attributes being keep in the internal dictionary.

    def __getattr__(self, name):
        """only called when an attribute lookup in the usual places has failed"""
        try:
            return self.my_dict[name]
        except KeyError:
            raise AttributeError("some customized error message")
    
    0 讨论(0)
  • 2020-12-07 09:09

    While in Java its indeed a bad practice to use Exceptions for flow control (mainly because exceptions force the jvm to gather resources (more here)), in Python you have 2 important principles: Duck Typing and EAFP. This basically means that you are encouraged to try using an object the way you think it would work, and handle when things are not like that.

    In summary the only problem would be your code getting too much indented. If you feel like it, try to simplify some of the nestings like lqc suggested in the suggested answer above.

    0 讨论(0)
  • 2020-12-07 09:11

    I don't think it's a matter of being pythonic or elegant. It's a matter of preventing exceptions as much as you can. Exceptions are meant to handle errors that might occur in code or events you have no control over. In this case you have full control when checking if an item is an attribute or in a dictionary, so avoid nested exceptions and stick with your second attempt.

    0 讨论(0)
  • 2020-12-07 09:13

    According to the documentation, it is better to handle multiple exceptions through tuples or like this:

    import sys
    
    try:
        f = open('myfile.txt')
        s = f.readline()
        i = int(s.strip())
    except IOError as e:
        print "I/O error({0}): {1}".format(e.errno, e.strerror)
    except ValueError:
        print "Could not convert data to an integer."
    except:
        print "Unexpected error:", sys.exc_info()[0]
        raise
    
    0 讨论(0)
提交回复
热议问题