ValueError兼容性和多行字符串美观性?

时间:2018-07-20 20:26:23

标签: python error-handling

我正在尝试以一种简洁,简洁的方式编写ValueError消息:

    raise ValueError("Model Architecture Not Recognized. Please ensure that your model's filename contains either"
    """ "vgg" and "16" for a 16 layer VGG model, "vgg" and "19" for a 19 layer VGG model, or "nin" for a Network"""
    " In Network model. Note that filenames are not case sensitive.")   

这对Python 2.7和Python 3都适用吗?有没有更好的方法来显示多行错误消息?在错误消息所用的字符串之间不使用+是否存在任何问题?

1 个答案:

答案 0 :(得分:2)

  

这对Python 2.7和Python 3都适用吗?

是的,字符串文字串联在Python 2Python 3中的工作方式相同。

  

是否有更好的方法来显示多行错误消息?

是的。特别是因为实际上这并不是多行错误消息。见下文。

  

在用于错误消息的字符串之间不使用+会有任何问题吗?

不,不。相邻的字符串文字被串联成一个字符串值。用+分隔的字符串文字定义了一堆单独的字符串值,然后要求Python在运行时将它们连接起来。但是,由于编译器知道表达式是由不变的常数组成,因此它将它们折叠成一个值。 1、2

但务实的是,很难读取这样的代码(尤其是当您尝试在80列的显示器(如典型的终端模式编辑器或Stack Overflow)上读取它时,尤其如此。作为读者,我怎么知道您是打算将三个字符串文字串联为一个值,还是要将三个字符串文字之间带有逗号作为三个单独的值传递给ValueError构造函数?好吧,如果我仔细看一下,再想一想,将另外两个字符串作为额外的参数传递给ValueError(尽管是合法的)没有什么意义,而这些空格使它看起来像是字符串一起走,依此类推...但是如果我不仔细看就能理解您的代码,将窗口向右滚动并考虑它会更好。因此,有时值得使用+甚至是像反斜杠连续之类的丑陋形式来避免这种混乱。


如上所述,您尚未生成多行字符串。琴弦被串联成一条巨线。似乎您已经知道这一点,或者您不会在第二个和第三个文字的开头加上空格。

如果您实际上想要多行字符串,则可以 在适当的位置添加\n字符来实现。

但是只编写多行字符串会容易得多:

raise ValueError("""Model Architecture Not Recognized. Please ensure that your model's filename contains either
    "vgg" and "16" for a 16 layer VGG model, "vgg" and "19" for a 19 layer VGG model, or "nin" for a Network
    In Network model. Note that filenames are not case sensitive.""")

或者,甚至更好的是,使用textwrap,这样您就可以在源代码中编写看起来不错但在输出方面看起来也不错的东西:

raise ValueError(textwrap.fill(textwrap.dedent("""
    Model Architecture Not Recognized. Please ensure that your model's
    filename contains either "vgg" and "16" for a 16 layer VGG model, 
    "vgg" and "19" for a 19 layer VGG model, or "nin" for a Network
    In Network model. Note that filenames are not case sensitive.
"""))

但是,如果您希望将其作为回溯的一部分进行打印,而不是except Exception as e: print(e),它仍然看起来很时髦:

ValueError:  Model Architecture Not Recognized. Please ensure that your model's
filename contains either "vgg" and "16" for a 16 layer VGG model,
"vgg" and "19" for a 19 layer VGG model, or "nin" for a Network In
Network model. Note that filenames are not case sensitive.

更好的解决方案可能是编写一个简短的错误字符串,再加上一个单独的长(多行,如果需要的话)描述字符串。您甚至可以通过转储长字符串来制作自己的ValueError子类来表示自己。您甚至可以将textwrap内容放入子类中。所以,你写,说:

raise ModelArchitectureError(
    "Model Architecture Not Recognized.",
    """Please ensure that your model's
        filename contains either "vgg" and "16" for a 16 layer VGG model, 
        "vgg" and "19" for a 19 layer VGG model, or "nin" for a Network
        In Network model. Note that filenames are not case sensitive.
    """))

或者更好的做法是为ModelArchitectureError的构造函数设置这些默认值,因此您可以执行以下操作:

raise ModelArchitectureError()

1。当然,Python不需要 require 这种常量求值,它只是允许它。 CPython 2.7和3.7,PyPy 6 2.7和3.5以及Jython 2.7都可以做到,但是其他一些实现可能不行。在那种情况下,+版本将具有相同的最终用户可见效果,但是要花更多的时间和临时内存(可能还有缓存空间和string-intern-table空间)。

2。如果编写一个导入钩子,然后在将其传递给编译器之前先在源代码,令牌或AST级别上转换代码,则可以想象这两个代码是不同的,因为在编译器/优化器使用它们之前它们不会变得相同。