Pythonでこの長い行を分割するにはどうすればよいですか?


176

このような長い行をフォーマットするにはどうしますか?幅を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

14
「it's」内の誤った 'を削除することで、キャラクターを保存できます。
jball

2
indexes:の正しい複数形はindexですindices
2015年

回答:


336

それが始まりです。それらを使用するコードの外で長い文字列を定義することは悪い習慣ではありません。データと動作を分離する方法です。最初のオプションは、文字列リテラルを互いに隣接させることによって暗黙的に結合することです。

("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の禅が言うように、明示的は暗黙的よりも優れていますが、これは1つではなく3つの文字列を作成し、2倍のメモリを使用します。禅を無視する時期を知る必要があります。利点は、各行の部分文字列のいずれかに個別に、または括弧の外側からロット全体にフォーマットを適用できることです。

最後に、三重引用符で囲まれた文字列を使用できます。

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

これには上記の同じ手法と同じ問題があります。正しいコードは、不可視の空白によって誤ったコードと異なるだけです。

どちらが「最適」かは、特定の状況によって異なりますが、答えは単に美的ではなく、微妙に異なる動作の1つです。


26
CPythonコンパイラはリテラル操作を可能な限り最適化します。つまり、2つの文字列リテラルを追加すると、バイトコード内の文字列リテラルは1つだけになります。
Ignacio Vazquez-Abrams

2
私が受け取った答えはすべて役に立ちましたが、あなたの答えは間違いなく、文字列を分割するすべての方法を理解するのに役立ちます。「\」行の終わりに問題がありましたが、その後にスペースがありましたか?
ガットスター、2013年

1
ここでは違いはわかりませんが、それは主にSOのかなり原始的な構文の色分けが原因です。(一部の完全に優れたコードは、SOでは実質的に読み取れませんが、構文がCに非常に近い言語にないためです。)エディターが不快に末尾のスペースを強調表示することは珍しいことではありません。 。:-)
Ken

1
@KhurshidAlam一重引用符'を使用してその文字列を含めるか、文字列内の二重引用符をエスケープするか、三重二重引用符を使用できます"""。引用符を含む引用符付き文字列の問題は、リテラル文字列を定義するために単一行を使用しても複数行を使用しても同じです。
hugovdberg

1
私のエディターは常に末尾の空白を削除します。同じ設定を有効にすることをお勧めします。もちろん、その後、新しい行の空白は文字列の一部なので、結局はを使用しました+
ThaJay

46

連続する文字列リテラルはコンパイラーによって結合され、括弧で囲まれた式は1行のコードと見なされます。

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

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

3
まだ80文字のルールに従っているプロジェクトはいくつあるのでしょうか。私が使用する平均ウィンドウサイズでは、80文字よりも100〜120の方が生産性が高いと思います。
Gattster

1
はい、それは私が使用するラインの長さについてですが、[ホラー!sacrilege!]私はプロポーショナルフォントを使用しているため、正確な行の長さはそれほど重要ではありません。文字数よりも、1行のロジックがどれだけ読みやすいかということです...誰も読む必要のない長いデータ文字列を取得した場合は、それをこぼしてしまいます120.
ボビンス2010年

コード用のプロポーショナルフォント-私はあなたと一緒にいます、兄弟。私がこれまで一緒に働いたすべての人が彼らのために持っていた嫌悪感から判断すると、世界は準備ができていません。
jlarcombe 2010年

4
〜80文字を使用すると、同じ画面で2つのファイルを並べて比較するのも簡単になります。また、サーバーのコンソールで緊急事態の間に何かをデバッグする場合、80文字の制限に本当に感謝します!:)
ミックT

4

あなたはtextwrapモジュールを使ってそれを複数行に分割することができます

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

ABCDEFGH
IJKLIMNO

ドキュメントから:

テキストの折り返し。wrap(text [、width [、...]])
単一の段落をテキスト(文字列)でラップします。これにより、すべての行が最大で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))

そうでなければ、唯一の可能性は、私が個人的には好きではない行末継続を使用することです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.