简体   繁体   中英

Python: store expected Exceptions in function attributes

Is it pythonic to store the expected exceptions of a funcion as attributes of the function itself? or just a stinking bad practice.

Something like this

class MyCoolError(Exception):
    pass

def function(*args):
    """
    :raises: MyCoolError

    """
    # do something here
    if some_condition:
        raise MyCoolError

function.MyCoolError = MyCoolError

And there in other module

try:
    function(...)
except function.MyCoolError:
    #...

Pro: Anywhere I have a reference to my function, I have also a reference to the exception it can raise, and I don't have to import it explicitly.

Con: I "have" to repeat the name of the exception to bind it to the function. This could be done with a decorator, but it is also added complexity.

EDIT

Why I am doing this is because I append some methods in an irregular way to some classes, where I think that a mixin it is not worth it. Let's call it "tailored added functionality". For instance let's say:

  • Class A uses method fn1 and fn2
  • Class B uses method fn2 and fn3
  • Class C uses fn4 ...
  • And like this for about 15 classes.

So when I call obj_a.fn2() , I have to import explicitly the exception it may raise (and it is not in the module where classes A, B or C, but in another one where the shared methods live)... which I think it is a little bit annoying. Appart from that, the standard style in the project I'm working in forces to write one import per line, so it gets pretty verbose.

In some code I have seen exceptions stored as class attributes, and I have found it pretty useful, like:

try:
    obj.fn()
except obj.MyCoolError:
    ....

I think it is not Pythonic. I also think that it does not provide a lot of advantage over the standard way which should be to just import the exception along with the function.

There is a reason (besides helping the interpreter) why Python programs use import statements to state where their code comes from; it helps finding the code of the facilities (eg your exception in this case) you are using.

The whole idea has the smell of the declaration of exceptions as it is possible in C++ and partly mandatory in Java. There are discussions amongst the language lawyers whether this is a good idea or a bad one, and in the Python world the designers decided against it, so it is not Pythonic.

It also raises a whole bunch of further questions. What happens if your function A is using another function B which then, later, is changed so that it can throw an exception (a valid thing in Python). Are you willing to change your function A then to reflect that (or catch it in A)? Where would you want to draw the line — is using int(text) to convert a string to int reason enough to "declare" that a ValueError can be thrown?

All in all I think it is not Pythonic, no.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM