你会如何格式化像这样长的一行呢?我想把它的宽度不超过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))

连续的字符串字面值由编译器连接,带括号的表达式被认为是一行代码:

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

就我个人而言,我不喜欢挂开块,所以我把它格式化为:

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

一般来说,我不会费心费力地让代码完全符合80列的行。将线长保持在合理的水平是值得的,但80的硬限制已经成为过去。


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

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

正如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."""

这与上面的相同技术存在相同的问题,因为正确代码与错误代码的区别仅在于不可见的空白。

哪一种是“最好的”取决于你的具体情况,但答案不是简单的审美,而是一种微妙的不同行为。


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

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

ABCDEFGH IJKLIMNO

从文档中可以看到:

textwrap。换行(text[, width[,…]]) 换行文本(字符串)中的单个段落,使每行最多为宽度字符长。返回一个输出行列表,没有最后的换行符。 可选关键字参数对应于TextWrapper的实例属性,如下所示。宽度默认为70。 有关wrap()行为的其他详细信息,请参阅TextWrapper.wrap()方法。


对于任何试图在长字符串上调用.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))

否则,唯一的可能就是使用行结束的延续,我个人并不喜欢这样做。


无需加载额外包的解决方案:

def split_by_len(txt: str, l: int, sep: str or None='\n') -> str or list:
    """
    txt: str text
    l: split length (symbols per split)
    sep: separate string or None for list of strs
    """
    spl_list = [txt[i * l : i * l + l] for i in range(len(txt) // l + 1)]
    return spl_list if sep==None else sep.join(spl_list)

示例1:

print(split_by_len(txt='XXXXX', l=2, sep='\n'))

XX
XX
X

示例2:

print(split_by_len(txt='XXXXX', l=2, sep=' '))

XX XX X

示例3:

print(split_by_len(txt='XXXXX', l=2, sep=None))

['XX', 'XX', 'X']