【问题标题】:How to write very long string that conforms with PEP8 and prevent E501如何编写符合 PEP8 的超长字符串并防止 E501
【发布时间】:2010-12-24 21:07:07
【问题描述】:

由于 PEP8 建议将您的 python 程序的列规则保持在 80 列以下,我如何才能遵守长字符串的规定,即

s = "this is my really, really, really, really, really, really, really long string that I'd like to shorten."

我将如何将其扩展到以下行,即

s = "this is my really, really, really, really, really, really" + 
    "really long string that I'd like to shorten."

【问题讨论】:

  • s = "这是我的"+"真的,"*6+"我想缩短的很长的字符串。" # 哎哟 ;-)

标签: python string pep8


【解决方案1】:

反斜杠:

s = "this is my really, really, really, really, really, really" +  \
    "really long string that I'd like to shorten."

或用括号括起来:

s = ("this is my really, really, really, really, really, really" + 
    "really long string that I'd like to shorten.")

【讨论】:

  • 注意加号是必须的。 Python 连接彼此跟随的字符串文字。
【解决方案2】:

使用\,您可以将语句扩展为多行:

s = "this is my really, really, really, really, really, really" + \
"really long string that I'd like to shorten."

应该可以。

【讨论】:

    【解决方案3】:

    你丢失了一个空格,你可能需要一个续行字符,即。 \

    s = "this is my really, really, really, really, really, really" +  \
        " really long string that I'd like to shorten."
    

    甚至:

    s = "this is my really, really, really, really, really, really"  \
        " really long string that I'd like to shorten."
    

    Parens 也可以代替行继续,但您可能会冒着有人认为您打算拥有一个元组并且忘记了逗号的风险。举个例子:

    s = ("this is my really, really, really, really, really, really"
        " really long string that I'd like to shorten.")
    

    对比:

    s = ("this is my really, really, really, really, really, really",
        " really long string that I'd like to shorten.")
    

    使用 Python 的动态类型,代码可能会以任何一种方式运行,但会产生与您不希望的结果不正确的结果。

    【讨论】:

      【解决方案4】:

      我认为您问题中最重要的词是“建议”。

      编码标准很有趣。通常,他们提供的指导在编写时具有非常好的基础(例如,大多数终端无法在一行上显示超过 80 个字符),但随着时间的推移,它们在功能上已经过时,但仍然严格遵守。我想您在这里需要做的是权衡“打破”该特定建议的相对优点与代码的可读性和可维护性。

      很抱歉,这并不能直接回答您的问题。

      【讨论】:

      • 我完全同意。有一个类似的 Java 样式规则也已过时(恕我直言)。
      • 是的,我同意,但是在这个特定的例子中我将如何遵守它一直在绞尽脑汁。我总是尝试将类、方法保持在
      • 您还需要根据社区范围的编码标准权衡您的个人偏好。从第一天开始,您希望新人能够进来并熟悉代码格式。
      • 我自己知道,我倾向于坚持 80 个字符的限制,因为我仍然在 IDLE 中进行大部分编码并且我不喜欢它处理水平滚动的方式。 (无滚动条)
      • @retracile - 是的,你做到了。我并不是说“你必须忽略指导”,而是建议在某些情况下,指导不一定是为了社区的利益。我不知道 IDLE 的限制(由 Tofystedeth 发布),但在这种情况下,有一个强烈的论据来遵循约定。
      【解决方案5】:

      隐式连接可能是最干净的解决方案:

      s = "this is my really, really, really, really, really, really," \
          " really long string that I'd like to shorten."
      

      编辑经过反思,我同意托德的建议使用括号而不是续行更好,因为他给出的所有原因。我唯一的犹豫是,括号字符串和元组比较容易混淆。

      【讨论】:

      • 这就是为什么我觉得自己像个白痴一样发布这个问题。干杯。
      • 这是通过转义结束行的行延续,而不仅仅是隐式连接,直到最近才在 PEP8 中明确禁止,尽管现在有允许,但不适用于长字符串。下面托德的回答是正确的。
      • 我喜欢 PEP8,但这是我不喜欢的 PEP8 的一部分。我觉得隐式延续更清晰,因为可能与元组混淆
      • 切记不要在\后面加空格
      【解决方案6】:

      由于相邻的字符串常量是自动连接的,你可以这样编码:

      s = ("this is my really, really, really, really, really, really, "  
           "really long string that I'd like to shorten.")
      

      注意没有加号,我在您的示例格式后面添加了额外的逗号和空格。

      就我个人而言,我不喜欢反斜杠,我记得在某处读到它实际上已被弃用,而是支持这种更明确的形式。记住“显式优于隐式。”

      我认为反斜杠不太清晰,也不太有用,因为它实际上是在转义换行符。如果有必要的话,不可能在它后面加上行尾注释。可以使用连接的字符串常量来做到这一点:

      s = ("this is my really, really, really, really, really, really, " # comments ok
           "really long string that I'd like to shorten.")
      

      我使用 Google 搜索“python line length”,它返回 PEP8 链接作为第一个结果,但也链接到另一个关于此主题的好 StackOverflow 帖子:“Why should Python PEP-8 specify a maximum line length of 79 characters?

      另一个很好的搜索短语是“python line continuation”。

      【讨论】:

      • +1:“我个人不喜欢反斜杠,我记得在某处读到它的使用实际上已被弃用,取而代之的是更明确的形式。记住“显式优于隐式。 ""
      • 对于所有获得元组并想知道为什么的人。不要在此处的行尾添加逗号,这将产生一个元组,而不是一个字符串。 ;)
      • 添加 + 字符不是比给定示例更明确吗?我仍然认为这是隐含的。即"str1" + "str2" 而不是"str1" "str2"
      • 我实际上同意加号更明确,但它做了不同的事情。它将字符串转换为要评估的表达式,而不是在多个部分中指定单个字符串常量。我不确定,但我认为这是在解析期间完成的,而表达式需要稍后执行。除非它们的数量很大,否则速度差异可能可以忽略不计。但在美学上,我更喜欢自动连接,因为它每行少一个杂乱的字符。
      • 此语法还保留了应用字符串格式的可能性,例如:('this is my really, really, really, really, really long {} ' 'that I'd really, really, really, like to {}').format(var1, var2))
      【解决方案7】:

      我倾向于使用此处未提及的几种方法来指定大字符串,但这些方法适用于非常具体的场景。 YMMV...

      • 多行文本块,通常带有格式化标记(不是您所要求的,但仍然有用):

        error_message = '''
        I generally like to see how my helpful, sometimes multi-line error
        messages will look against the left border.
        '''.strip()
        
      • 通过您喜欢的任何字符串插值方法逐段增长变量:

        var = 'This is the start of a very,'
        var = f'{var} very long string which could'
        var = f'{var} contain a ridiculous number'
        var = f'{var} of words.'
        
      • 从文件中读取。 PEP-8 不限制文件中字符串的长度;只是你的代码行。 :)

      • 使用蛮力或您的编辑器使用换行符将字符串拆分为可管理的行,然后删除所有换行符。 (类似于我列出的第一种技术):

        foo = '''
        agreatbigstringthatyoudonotwanttohaveanyne
        wlinesinbutforsomereasonyouneedtospecifyit
        verbatimintheactualcodejustlikethis
        '''.replace('\n', '')
        

      【讨论】:

        【解决方案8】:

        我过去使用过 textwrap.dedent。这有点麻烦,所以我现在更喜欢行延续,但如果你真的想要块缩进,我认为这很棒。

        示例代码(修剪是用切片去掉第一个'\n'):

        import textwrap as tw
        x = """\
               This is a yet another test.
               This is only a test"""
        print(tw.dedent(x))
        

        解释:

        dedent 根据换行前第一行文本中的空白计算缩进。如果您想对其进行调整,您可以使用 re 模块轻松地重新实现它。

        此方法的局限性在于,很长的行可能仍然比您想要的长,在这种情况下,连接字符串的其他方法更合适。

        【讨论】:

        • 您可以在x = """ 之后放置反斜杠,而不是使用x[1:] 进行修剪,以避免出现第一个换行符。
        【解决方案9】:

        这些都是很好的答案,但我找不到可以帮助我编辑“隐式连接”字符串的编辑器插件,所以我写了一个包来让我更轻松。

        在 pip (安装段落)上,如果谁在这个旧线程上徘徊想检查一下。以 html 的方式格式化多行字符串(压缩空格,新段落的两个换行符,不用担心行之间的空格)。

        from paragraphs import par
        
        
        class SuddenDeathError(Exception):
            def __init__(self, cause: str) -> None:
                self.cause = cause
        
            def __str__(self):
                return par(
                    f""" Y - e - e - e - es, Lord love you! Why should she die of
                    {self.cause}? She come through diphtheria right enough the year
                    before. I saw her with my own eyes. Fairly blue with it, she
                    was. They all thought she was dead; but my father he kept ladling
                    gin down her throat till she came to so sudden that she bit the bowl
                    off the spoon. 
        
                    What call would a woman with that strength in her have to die of
                    {self.cause}? What become of her new straw hat that should have
                    come to me? Somebody pinched it; and what I say is, them as pinched
                    it done her in."""
                )
        
        
        raise SuddenDeathError("influenza")
        
        

        变成...

        __main__.SuddenDeathError: Y - e - e - e - es, Lord love you! Why should she die of influenza? She come through diphtheria right enough the year before. I saw her with my own eyes. Fairly blue with it, she was. They all thought she was dead; but my father he kept ladling gin down her throat till she came to so sudden that she bit the bowl off the spoon.
        
        What call would a woman with that strength in her have to die of influenza? What become of her new straw hat that should have come to me? Somebody pinched it; and what I say is, them as pinched it done her in.
        

        使用 (Vim) 'gq' 可以轻松匹配所有内容

        【讨论】:

          【解决方案10】:

          可用选项:

          • 反斜杠"foo" \ "bar"
          • 加号后跟反斜杠"foo" + \ "bar"
          • 括号
            • ("foo" "bar")
            • 括号加号("foo" + "bar")
            • PEP8、E502:括号之间的反斜杠是多余的

          避免

          避免使用逗号的括号:("foo", "bar"),它定义了一个元组。


          >>> s = "a" \
          ... "b"
          >>> s
          'ab'
          >>> type(s)
          <class 'str'>
          
          >>> s = "a" + \
          ... "b"
          >>> s
          'ab'
          >>> type(s)
          <class 'str'>
          
          >>> s = ("a"
          ... "b")
          >>> type(s)
          <class 'str'>
          >>> print(s)
          ab
          
          >>> s = ("a",
          ... "b")
          >>> type(s)
          <class 'tuple'>
          
          >>> s = ("a" + 
          ... "b")
          >>> type(s)
          <class 'str'>
          >>> print(s)
          ab
          >>> 
          

          【讨论】:

            【解决方案11】:

            如果你必须插入一个长字符串文字并希望 flake8 闭嘴,你可以使用它shutting up directives。例如,在一个测试例程中,我定义了一些虚假的 CSV 输入。我发现将其拆分为更多行会非常混乱,因此我决定添加# noqa: E501,如下所示:

            csv_test_content = """"STATION","DATE","SOURCE","LATITUDE","LONGITUDE","ELEVATION","NAME","REPORT_TYPE","CALL_SIGN","QUALITY_CONTROL","WND","CIG","VIS","TMP","DEW","SLP","AA1","AA2","AY1","AY2","GF1","MW1","REM"
            "94733099999","2019-01-03T22:00:00","4","-32.5833333","151.1666666","45.0","SINGLETON STP, AS","FM-12","99999","V020","050,1,N,0010,1","22000,1,9,N","025000,1,9,9","+0260,1","+0210,1","99999,9","24,0000,9,1",,"0,1,02,1","0,1,02,1","01,99,1,99,9,99,9,99999,9,99,9,99,9","01,1","SYN05294733 11/75 10502 10260 20210 60004 70100 333 70000="
            "94733099999","2019-01-04T04:00:00","4","-32.5833333","151.1666666","45.0","SINGLETON STP, AS","FM-12","99999","V020","090,1,N,0021,1","22000,1,9,N","025000,1,9,9","+0378,1","+0172,1","99999,9","06,0000,9,1",,"0,1,02,1","0,1,02,1","03,99,1,99,9,99,9,99999,9,99,9,99,9","03,1","SYN04294733 11/75 30904 10378 20172 60001 70300="
            "94733099999","2019-01-04T22:00:00","4","-32.5833333","151.1666666","45.0","SINGLETON STP, AS","FM-12","99999","V020","290,1,N,0057,1","99999,9,9,N","020000,1,9,9","+0339,1","+0201,1","99999,9","24,0000,9,1",,"0,1,02,1","0,1,02,1",,"02,1","SYN05294733 11970 02911 10339 20201 60004 70200 333 70000="
            "94733099999","2019-01-05T22:00:00","4","-32.5833333","151.1666666","45.0","SINGLETON STP, AS","FM-12","99999","V020","200,1,N,0026,1","99999,9,9,N","000100,1,9,9","+0209,1","+0193,1","99999,9","24,0004,3,1",,"1,1,02,1","1,1,02,1","08,99,1,99,9,99,9,99999,9,99,9,99,9","51,1","SYN05294733 11/01 82005 10209 20193 69944 75111 333 70004="
            "94733099999","2019-01-08T04:00:00","4","-32.5833333","151.1666666","45.0","SINGLETON STP, AS","FM-12","99999","V020","070,1,N,0026,1","22000,1,9,N","025000,1,9,9","+0344,1","+0213,1","99999,9","06,0000,9,1",,"2,1,02,1","2,1,02,1","04,99,1,99,9,99,9,99999,9,99,9,99,9","02,1","SYN04294733 11/75 40705 10344 20213 60001 70222="
            """  # noqa: E501
            

            【讨论】:

              【解决方案12】:

              使用 black [https://github.com/psf/black] 我将其格式化为这样。

                 help=f"""filters, lista de filtros para cargar las base de conocimiento.
                 Pueden mandarse solo algunos filtros ya que no son obligatorios,
                 por ejemplo, si no se manda sts, se cargarán todos las bases de todos los estados.""",
              

              【讨论】:

                【解决方案13】:
                message = f"Variable : child({type(child)}) -> is not of"\
                        " type Node."
                

                这种语法对我有用。注意第二条语句的缩进,应该缩进正确。

                【讨论】:

                  猜你喜欢
                  • 2014-11-14
                  • 2013-02-08
                  • 2017-02-24
                  • 2020-07-25
                  • 2017-02-21
                  • 1970-01-01
                  • 2016-06-23
                  • 2018-09-19
                  • 2013-10-10
                  相关资源
                  最近更新 更多