简体   繁体   English

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

[英]ValueError compatibility and multi-line string aesthetics?

I am trying to write a ValueError message in a nice compact, and clean looking way: 我试图以一种简洁,简洁的方式编写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.")   

Will this work for both Python 2.7 and Python 3? 这对Python 2.7和Python 3都适用吗? Is there a better way to have a multi-line error message? 有没有更好的方法来显示多行错误消息? Are there any issues with not using a + in between the strings used for the error message? 在错误消息所使用的字符串之间不使用+会有任何问题吗?

Will this work for both Python 2.7 and Python 3? 这对Python 2.7和Python 3都适用吗?

Yes, string literal concatenation works the same way in Python 2 and Python 3 . 是的,字符串文字串联在Python 2Python 3中的工作方式相同。

Is there a better way to have a multi-line error message? 有没有更好的方法来显示多行错误消息?

Yes. 是。 Especially since this isn't actually a multi-line error message in the first place. 特别是因为实际上这并不是多行错误消息。 See below. 见下文。

Are there any issues with not using a + in between the strings used for the error message? 在错误消息所使用的字符串之间不使用+会有任何问题吗?

Semantically, no. 从语义上讲,不。 Adjacent string literals are concatenated into a single string value. 相邻的字符串文字被串联成一个字符串值。 String literals separated by + define a bunch of separate string values, then ask Python to concatenate them at runtime. +分隔的字符串文字定义了一堆单独的字符串值,然后要求Python在运行时将它们连接起来。 But, because the compiler knows that the expression is made up of nothing but immutable constants, it will fold them together into a single value. 但是,由于编译器知道表达式仅由不可变的常数组成,因此它将它们折叠为一个值。 1, 2 一二

But pragmatically, it can be hard to read code like this (especially when you're trying to read it on an 80-column display like a typical terminal-mode editor, or Stack Overflow). 但务实的是,很难读取这样的代码(尤其是当您尝试在80列的显示器(例如典型的终端模式编辑器或Stack Overflow)上阅读该代码时。 As a reader, how do I know whether you intended three string literals to be concatenated into one value, or three string literals with commas between them to be passed as three separate values to the ValueError constructor? 作为读者,我怎么知道您打算将三个字符串文字连接成一个值,还是要将三个字符串文字之间带有逗号作为三个单独的值传递给ValueError构造函数? Well, if I look carefully, and think about it, there's not much point to passing those two other strings as extra arguments to a ValueError (even though it's legal), and those spaces make it look like the strings are meant to go together, and so on… but it would be better if I could understand you code without looking carefully, scrolling the window to the right, and thinking about it. 好吧,如果我仔细看一下,再想一想,将另外两个字符串作为额外参数传递给ValueError没什么意义(尽管这是合法的),并且这些空格使它们看起来像是字符串一样,依此类推...但是如果我不仔细看就能理解您的代码,将窗口向右滚动并考虑它会更好。 So, sometimes it's worth using a + , or even something ugly like backslash continuation, to avoid that confusion. 因此,有时值得使用+或类似反斜杠连续之类的丑陋形式来避免这种混淆。


As mentioned above, you haven't produced a multi-line string. 如上所述,您尚未生成多行字符串。 The strings get concatenated into one giant line. 琴弦被串联成一条巨线。 And it seems like you already know this, or you wouldn't have prepended a space to the start of the second and third literals. 似乎您已经知道这一点,或者您不会在第二个和第三个文字的开头加上空格。

If you actually want a multiline string, you could do that by adding \\n characters in appropriate places. 如果您确实需要多行字符串,则可以通过在适当的位置添加\\n字符来实现。

But it's a lot easier to just write a multiline string: 但是编写多行字符串要容易得多:

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.""")

Or, even better, use textwrap , so you can write something that looks nice in your source but also looks nice on output: 或者,甚至更好的方法是使用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.
"""))

But if you're expecting this to be printed as part of a traceback, rather than, say, except Exception as e: print(e) , it's still going to look funky: 但是,如果您希望将其作为回溯的一部分进行打印,而不是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.

A better solution is probably to write a short error string plus a separate long (multi-line, if you want) description string. 更好的解决方案可能是编写一个简短的错误字符串,再加上一个单独的长长的(多行,如果需要的话)描述字符串。 You can even make your own ValueError subclass that represents itself by dumping the long string. 您甚至可以通过转储长字符串来制作自己的ValueError子类来表示自身。 You can even throw the textwrap stuff into the subclass. 您甚至可以将textwrap内容放入子类中。 So then, you'd write, say: 所以,你会写,说:

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.
    """))

Or, even better, make those default values for the ModelArchitectureError 's constructor, so you can just do this: 或者,甚至更好的是,为ModelArchitectureError的构造函数设置这些默认值,因此您可以执行以下操作:

raise ModelArchitectureError()

1. Of course Python doesn't require this constant evaluation, it just allows it. 1.当然,Python 不需要这种常量求值,而只是允许它。 CPython 2.7 and 3.7, PyPy 6 2.7 and 3.5, and Jython 2.7 all do it, but some other implementation might not. CPython 2.7和3.7,PyPy 6 2.7和3.5以及Jython 2.7都可以做到,但是其他一些实现可能不行。 In that case, the + version would have the same end-user-visible effect, but it would take more time and temporary memory (and possibly cache space and string-intern-table space) to do it. 在那种情况下, +版本将具有相同的最终用户可见效果,但是要花更多时间和临时内存(可能还需要缓存空间和string-intern-table空间)。

2. If you write an import hook that transforms the code at the source, token, or AST level before passing it to the compiler, the two could conceivably be different, because they don't become the same until the compiler/optimizer gets to it. 2.如果您编写了一个导入钩子,然后在将其传递给编译器之前先在源代码,令牌或AST级别上转换代码,则可以想象两者可能是不同的,因为在编译器/优化器进入编译器/优化器之前,它们不会变得相同。它。

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

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