简体   繁体   English

Python:将预期的异常存储在函数属性中

[英]Python: store expected Exceptions in function attributes

Is it pythonic to store the expected exceptions of a funcion as attributes of the function itself? 将函数的预期异常存储为函数本身的属性是否为pythonic? 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. Pro:在我对函数的引用中,也对它可能引发的异常的引用,也不必显式导入。

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. 我之所以这样做,是因为我以不规则的方式将某些方法附加到某些类上,在这些类中,我认为不值得使用mixin。 Let's call it "tailored added functionality". 我们称其为“量身定制的功能”。 For instance let's say: 例如,让我们说:

  • Class A uses method fn1 and fn2 Class A使用方法fn1fn2
  • Class B uses method fn2 and fn3 Class B使用方法fn2fn3
  • Class C uses fn4 ... Class C使用fn4 ...
  • And like this for about 15 classes. 像这样大约15个班级。

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. 因此,当我调用obj_a.fn2() ,我必须显式导入它可能引发的异常(它不在类A,B或C所在的模块中,而是在共享方法所在的另一类中)...我认为这有点烦人。 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. Appart从此开始,我正在努力的项目中的标准样式迫使每行编写一个导入,因此它变得非常冗长。

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. 我认为这不是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; 有一个原因(除了帮助解释器外),为什么Python程序使用import语句来说明其代码的来源; 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. 整个想法都有异常声明的味道,因为在C ++中是可能的,而在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. 语言律师之间一直在讨论这是一个好主意还是一个坏主意,在Python世界中,设计人员决定反对它,因此这不是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). 如果您的函数A使用另一个函数B,然后又对其进行了更改以使其可以引发异常(在Python中是有效的东西),将会发生什么。 Are you willing to change your function A then to reflect that (or catch it in A)? 您是否愿意先更改函数A使其反映(或在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? 您想在哪里画线—使用int(text)将字符串转换为int的原因足以“声明”可以抛出ValueError

All in all I think it is not Pythonic, no. 总而言之,我认为这不是Pythonic,不是。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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