如何在Python中打破这条漫长的路线?


175

您将如何格式化这样的长行?我希望宽度不超过80个字符:

logger.info("Skipping {0} because its thumbnail was already in our system as {1}.".format(line[indexes['url']], video.title))

这是我最好的选择吗?

url = "Skipping {0} because its thumbnail was already in our system as {1}."
logger.info(url.format(line[indexes['url']], video.title))

1
似乎是一个不错的选择。你不喜欢它什么?
Hamish Grubijan 2010年

2
有点主观,不是吗?:)
AdamWoś10年

1
相关:stackoverflow.com/questions/1940710/… (Python中的字符串连接)
jldupont 2010年

14
您可以通过删除“它的”中不正确的“”来保存字符。
jball 2010年

2
indexes:正确复数indexindices
2015年

Answers:


335

那是一个开始。在使用长字符串的代码之外定义较长的字符串并不是一个坏习惯。这是分离数据和行为的一种方式。您的第一个选择是通过使字符串文字彼此相邻来隐式地将它们连接在一起:

("This is the first line of my text, "
"which will be joined to a second.")

或使用行尾连续符,这会更脆弱一些,因为这可行:

"This is the first line of my text, " \
"which will be joined to a second."

但这不是:

"This is the first line of my text, " \ 
"which will be joined to a second."

看到不同?没有?好吧,当它是您的代码时,您也不会。

隐式连接的不利之处在于,它仅适用于字符串文字,而不适用于从变量中提取的字符串,因此在进行重构时,事情可能会变得更加复杂。另外,您只能对整个组合字符串进行插值格式化。

另外,您可以使用串联运算符(+)显式加入:

("This is the first line of my text, " + 
"which will be joined to a second.")

正如zen python所说的那样,显式比隐式更好,但这会创建三个字符串而不是一个字符串,并且使用两倍的内存:您已经编写了两个字符串,再加上一个字符串,即两个字符串连接在一起,所以您必须知道何时忽略禅宗。好处是您可以将格式分别应用于每一行中的任何子字符串,也可以应用于位于括号外的全部子字符串。

最后,您可以使用三引号引起来的字符串:

"""This is the first line of my text
which will be joined to a second."""

这通常是我的最爱,尽管它的行为略有不同,因为换行符和后续行中的任何前导空格都会显示在您的最终字符串中。您可以使用转义的反斜杠消除换行符。

"""This is the first line of my text \
which will be joined to a second."""

这具有与上述相同技术相同的问题,因为正确的代码与不正确的代码的区别仅在于不可见的空格。

哪一个“最佳”取决于您的特定情况,但答案不只是简单的美学,而是微妙的不同行为之一。


26
CPython编译器会尽可能优化文字操作,这意味着添加两个字符串文字只会导致字节码中只有一个字符串文字。
伊格纳西奥·巴斯克斯

2
虽然我收到的所有答案都是有帮助的,但您的答案肯定可以帮助我理解分解字符串的所有方法。“ \”行结尾是否有空格是问题吗?
Gattster 2010年

1
我在这里看不到区别,但是那主要是因为SO的语法很原始。(有些完美的代码实际上在SO上是不可读的,但这仅是因为它不是使用语法非常接近C的语言。)使您的编辑器令人讨厌地突出显示尾随空格并不罕见,因为它们很少有用(或故意) 。:-)

1
@KhurshidAlam可以使用单引号'包含该字符串,或者在字符串内转义双引号,或者使用三重双引号"""。无论使用单行还是多行来定义文字字符串,带引号的带引号的字符串的问题都是相同的。
hugovdberg

1
我的编辑器总是删除尾随空格。我建议您启用相同的设置。当然,新行中的空格仍然是字符串的一部分,因此我最终使用+
ThaJay


11

我个人不喜欢挂空块,所以我将其格式化为:

logger.info(
    'Skipping {0} because its thumbnail was already in our system as {1}.'
    .format(line[indexes['url']], video.title)
)

通常,我不会太费力地使代码完全适合80列行。可以将线长降低到合理的水平,但是硬80的限制已成过去。


8
这已经不是过去了。Python标准库仍然使用PEP8作为其样式指南,因此该规则仍然存在,并且很多人(包括我自己)都遵循它。这是画线的方便地方。
Devin Jeanpierre 2010年

3
我想知道还有多少项目仍遵循80 char规则。对于我使用的平均窗口大小,我认为100-120比80个字符对我的生产率更高。
Gattster 2010年

1
是的,这也差不多是我使用的行长,尽管[恐怖!牺牲!]我使用比例字体,因此确切的行长不是那么关键。与其说是多少个字符,不如说是一行上可读的逻辑更多,例如……如果我有一长串不需要任何人读取的数据,我很乐意让它溢出120.
bobince 2010年

代码的比例字体-兄弟,我和你在一起。从我曾经与之共事的每个人的厌恶来看,这个世界还没有准备好。
jlarcombe 2010年

4
约80个字符还使在同一屏幕上并排比较两个文件变得更加容易。此外,如果您在服务器控制台的紧急情况下调试某些内容,您将真正体会到80个字符的限制!:)
Mick T

4

您可以使用textwrap模块将其分成多行

import textwrap
str="ABCDEFGHIJKLIMNO"
print("\n".join(textwrap.wrap(str,8)))

ABCDEFGH
IJKLIMNO

文档中

文本换行。wrap(text [,width [,...]])
将单个段落包装在文本(字符串)中,因此每一行最多为宽度字符。返回输出行列表,不带最终换行符。

可选的关键字参数与的实例属性相对应TextWrapper,如下所述。宽度默认为70

有关TextWrapper.wrap()wrap()行为的更多详细信息,请参见方法。


2

对于也尝试调用.format()长字符串并且在不中断后续.format(调用的情况下无法使用某些最受欢迎的字符串包装技术的任何人,您可以使用str.format("", 1, 2)代替"".format(1, 2)。这使您可以使用任何喜欢的技术来断开字符串。例如:

logger.info("Skipping {0} because its thumbnail was already in our system as {1}.".format(line[indexes['url']], video.title))

logger.info(str.format(("Skipping {0} because its thumbnail was already"
+ "in our system as {1}"), line[indexes['url']], video.title))

否则,唯一的可能性就是使用行尾延续,我个人并不喜欢。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.