Add more information about all python exceptions

After another terrible hunt for errors, I am interested in the following: Is it possible to add additional information to all exceptions, for example, the name of the object. This would significantly increase the readability of errors and speed up the search for errors (or input errors). This is especially important if one has many objects that belong to the same class and therefore have a lot of code but have different attributes. In this case, this can be very useful if the error message also indicates the name of the object in the error.

A simple example: I'm trying to model different types of objects, a pig farm and a cow farm. This is the same class, but have different attributes. Many objects are created in the simulation, and if an exception occurs, it would be very useful if the name of the object was added to the exception.

class facility():
    def __init__(self, name):
        self.name = name
        self.animals = []

farms = []
farms.append(facility('cow_farm'))
farms.append(facility('pig_farm'))
print farms[0].stock

It will give

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: facility instance has no attribute 'stock'

But I would like to add an object name:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: facility instance has no attribute 'stock'
  Name of object: cow_farm

I tried something like

def print_name(exception):
    try:
        print self.name
    except AttributeError:
        pass
    raise exception

@print_name
Exception

But that does not work. Is it possible to do this, or is there any good reason not to do this?

+4
source share
2 answers

If you want to handle errors and add information, you can do it as follows:

farm = farms[0]
try:
    print farm.stock
except AttributeError:
    raise AttributeError("{} has no attribute 'stock'".format(farm.name))

However, it would be wiser to add an empty stockin __init__to avoid this error.

except, ( !) , try , . try, :

try:
    print farm.stock["hay"]
except AttributeError:
    raise AttributeError("{} has no attribute 'stock'".format(farm.name))
except KeyError:
    raise KeyError("{} has no 'hay' in 'stock'".format(farm.name))

( , self.stock __init__ if "hay" in farm.stock: .)

, , , . -:

def some_func(*args, **kwargs):
    try:
        # all of some_func content goes here
    except:
        raise Exception("Something went wrong in some_func().")

, .

AttributeError class, :

class Facility(object):

    def __init__(self, ...):
        ...

    def __getattr__(self, key):
        """Called on attempt to access attribute instance.key."""
        if key not in self.__dict__:
            message = "{} instance '{}' has no attribute '{}'."
            message = message.format(type(self).__name__,
                                     self.name, key)
            raise AttributeError(message)
        else:
            return self.__dict__[key]

>>> farm = Facility("pig farm")
>>> print farm.stock
...
"AttributeError: Facility instance 'pig farm' has no attribute 'stock'."

, :

class ProtectedAttrs(object):

    def __init__(self, name):
        self.name = name

    def __getattr__(self, key):
        ...

class Facility(ProtectedAttrs):

    def __init__(self, name):
        super(Facility, self).__init__(name)
        self.animals = []

. , - .

+2

,

In [163]: try:
   .....:     farm = []
   .....:     farm.stock
   .....: except AttributeError as err:
   .....:     print err.message
   .....:     
'list' object has no attribute 'stock'

,

-1

All Articles