Pythonでのコメント; 文字列のフォーマット:フォーマット演算子とFormat()メソッド。 §2。 フォーマットされた出力。 print()関数。 Format()メソッド

コメント(1)

この段階では、すでにかなり広範なツールセットがあり、かなり「紛らわしい」コードを記述できます。 数十行のコードを書いた後、数日後、読むのはかなり難しくなります。 他の人にとっては、それを読むのはさらに難しいでしょう。
そして、私たちが大規模なプロジェクトでそれを想像すると、メガバイト テキストファイルコードを使用すると、読みにくくなります。 この状況は、コード内のコメントによって保存されます。 これらのコメント、プログラマーは、時間の経過とともに、このコードまたはそのコードの一部を明確にし、特定の部分で発生するいくつかのアクションを説明できるように残します プログラムコード..。 同僚にとってもあなたにとっても、これによりコードの読みやすさが大幅に向上します。

Pythonは、単一行と複数行の2種類のコメントを区別します。 1行のコメントは「#」文字で始まり、別の行に置くことも、コードで1行を終了することもできますが、1行のコメントである必要があります。 2行に分割しないでください。 コードの行を終了することはできますが、2つのコードの間の行の途中にすることはできません。 例えば:

i = 0#ループのカウンター

#ループは上記の条件に基づいて実行されます

複数行コメントは、三重引用符 "" "で囲まれています。複数行に分割して非常に長くすることができます。実際、エッセイを書くこともできます。複数行コメントは、新しい行で開始する必要があり、他の行に続けることができます。行。例:

"" "リストを調べて必要な要素を見つけます

見つけたら、ループを終了し、結果を変数xに保存します。

必要な要素が見つからない場合は、ユーザーに通知してください "" "

1行のコメントは、対応するブロックのコードと同じインデントで開始する必要があることに注意してください。そうでない場合、トラックバックが発生します。 同様に、複数行コメントは、コードのブロックに対応するインデントで始まる必要があります。 コメントの後続の行では、インデントを保持する必要はありません。インデントは、冒頭の引用符 "" "の前にのみ配置する必要があります。

初心者だけでなく、初心者のプログラマーも、「ここで変数xを宣言しました」のように、コメントに明白なことを書くことがよくあります。 人間の言葉で実行されたアクションを複製するコメントは避けてください。 コメントを書く前に、「このスニペットは何のためにあるのか」、「このスニペットで何を追求しているのか」、「このスニペットで何をしているのか」などの質問をしてみてください。これは、将来的にコードを維持し、読みやすくするのに役立つ適切なコメントを作成するのに役立ちます。

文字列フォーマット演算子

さて、「文字列フォーマット」という表現は、文字列内の変数の値を拡張することを意味します。 行が必要な場合は、いくつかの変数の値を挿入します。 以前は、「+」(文字列の連結)と「、」を使用して、行の後に数式を記​​述していました。 少なくとも醜いように見えた。

>>> a = "こんにちは"

>>> b = "親愛なる"

>>> a + "" + b

変数値を連続して展開する標準的な方法は2つあります。 次に、書式設定演算子を使用して書式設定する方法について説明します。 このメソッドは古く、時代遅れで、使い勝手が悪く、使いたくないものですが、古いコードでよく使用されます。

次のオプションを考えてみましょう。

>>> a = "Vasya"

>>> print "Hello%s"%a

こんにちはVasya

何が起こっていますか? すべてが十分に単純です。 行の%s演算子は、行の後の%記号の右側にある変数に置き換えられます。

別の例を見てみましょう:

>>> name = "Vasya"

>>> lastname = "Pupkin"

>>>年齢= 25

>>> print "First name%s、lastname%s、age%d"%(name、lastname、age)

ファーストネームVasya、ラストネームPupkin、25歳

まず、複数の変数がある場合は、それらをタプル()で渡すことに注意してください。 また、%s演算子を使用して変数の文字列値を渡し、%d演算子を使用して数値を参照する変数に渡したことに気付いたかもしれません。 これが機能する唯一の方法です。 各演算子は、特定のタイプの値を展開できます。文字列の場合は%s、数値の場合は%dなどです。 演算子のより詳細なリストを以下に示します。

最初の質問は、「1つの変数の値を1行に数回表示するにはどうすればよいですか?」というものです。 答えは明らかです。この変数をタプルに何度も、文字列内のこれらの変数の値を展開する順序で渡す必要があります。 不器用で不便です。 変数は、演算子が1行で展開する方法と一致する厳密な順序で常に記述し、必要に応じて繰り返す必要があります。

フォーマット演算子のリスト:

%d、%i、%u

10進数。

8進数。

16進数(小文字)。

16進数(大文字)。

指数(小文字の指数)を使用した浮動小数点数。

指数(大文字の指数)を含む浮動小数点数。

浮動小数点(通常の形式)。

浮動小数点数。 -4未満の場合は指数(小文字の指数)、それ以外の場合は通常の形式。

浮動小数点数。 -4未満の場合は指数(大文字の指数)、それ以外の場合は通常の形式。

文字(1文字または数字の文字列-文字コード)。

文字列(Pythonリテラル)。

文字列(通常はユーザーが認識します)。

フォーマット演算子(オプション)

ここで簡単に説明します 追加機能書式設定演算子。

変換指定子は次の順序で記述されます。

2.キー(オプション)。値のどの引数が置換されるかを決定します。

3.変換フラグ。

4.最小フィールド幅。 *の場合、値はタプルから取得されます。

5.精度、「。」で始まり、次に必要な精度。

6.長さ修飾子(オプション)。

7.入力します(上の表を参照)。

>>> print( "%(language)s has%(number)03d quote types。"%( "language": "Python"、 "number":2))

Pythonには002の引用タイプがあります。

変換フラグ:

値は別の形式を使用します。

空き領域はゼロで埋められます。

空きスペースは右側のスペースで埋められます。

空のスペースは左側のスペースで埋められます。

>>> "%.2s"% "こんにちは!"

>>> "%。* s"%(2、 "こんにちは!")

>>> "%-10d"%25

>>> "%+ 10f"%25

>>> "%+ 10s"% "こんにちは"

これらの機能はまれにしか使用されないため、これらの機能をより詳細に分析することは意味がありません。

文字列のフォーマット方法format()

フォーマット演算子は文字列メソッドに置き換えられました フォーマット ()..。 この方法は、はるかに柔軟で、便利で、用途が広いです。 文字列内の変数値を展開するためにどのように使用できるかを見てみましょう。

>>> name = "Vasya"

>>> lastname = "Pupkin"

>>>年齢= 25

>>> print "()()、age()"。format(name、lastname、age)

Vasya Pupkin、25歳

ここではすべてがかなり明白です。 中括弧()は、文字列内の変数を展開する場所を定義し、format()メソッドに、展開する変数を渡します。 一見したところ、書式設定演算子と比較して何も変わっていません。 まだ展開を制御することはできません。 唯一の違いは、値を拡張するために多数の演算子を記憶する必要がなくなったことです。 他の種類..。 何も、これはほんの始まりにすぎません。 一貫して機能を構築していきましょう。 次のオプションを考えてみましょう。

>>> name = "Vasya"

>>> lastname = "Pupkin"

>>>年齢= 25

>>> print "(0)(1)、age(2)"。format(name、lastname、age)

Vasya Pupkin、25歳

何も変更されていませんが、中括弧内にいくつかの数字が追加されています。 次の例を参照してください。

>>> print "(1)(0)、age(2)"。format(name、lastname、age)

Pupkin Vasya、25歳

出力文字列が変更されました。値を交換しました。 メソッドに渡した変数を交換する必要はなく、中括弧()内の数値を交換しただけであることに気付いたかもしれません。 これらの数値は、ラインで拡張したい変数の一種のインデックスです。 最後の例では、インデックス1、次に0と2で変数を展開しました。つまり、 メソッドに渡される2番目、1番目、3番目の変数。 これは、メソッドに渡された変数のインデックスを指定することで、必要な順序でそれらを展開できることを意味します。 また、中括弧で囲まれたインデックスを数回指定することで、文字列内の1つの変数の値を数回表示できます。

>>> print "(1)(1)、age(2)"。format(name、lastname、age)

パプキンパプキン、25歳

同意します。これは、フォーマット演算子と比較して、文字列をフォーマットするためのはるかに柔軟で便利な方法です。 しかし、変数の値を拡張するためのこの方法の柔軟性は、それだけではありません。 名前付き引数の変形を考えてみましょう。

>>> a = "Vasya"

>>> b = "パプキン"

>>> print "(name)(lastname)、age(age)"。format(age = c、name = a、lastname = b)

Vasya Pupkin、25歳

これはさらに興味深いものです。 必要なデータは、非発話変数a、b、およびcの下にありました。 これらの変数をメソッドに渡すときは、(name = variable)のような意味のある名前を付けてから、中括弧()でこれらの名前を使用しました。

formatメソッドに、値のリストを渡し、文字列内でそれらを展開できます。 それは次のように起こります:

>>> l = ["Vasya"、 "Pupkin"、25]

["Vasya"、 "Pupkin"、25]

>>> print "(0)(1)、age(2)"。format(* l)

Vasya Pupkin、25歳

ここではすべてが明白です。 リストを渡し、インデックスでその要素にアクセスしましたが、リストを渡すときは、変数の前に「*」記号を指定しました。これは、このリストの要素を展開することをformat()メソッドに明示的に指示しました。 コンボ引数の前の「*」を省略するとどうなりますか?

>>> print "(0)(1)、age(2)"。format(l)

トレースバック(最後の最後の呼び出し):

ファイル ""、1行目、

IndexError:タプルインデックスが範囲外です

メソッドは、リストが渡されたことを認識せず、文字列でアクセスしたインデックス1と2で通常の引数を検索しようとしていました。

同様に、format()メソッドと辞書を渡すことができます。

>>> db =( "name": "Vasya"、 "lastname": "Pupkin"、 "age":25)

( "姓": "パプキン"、 "年齢":25、 "名前": "ヴァシャ")

>>> print "(name)(lastname)、age(age)"。format(** db)

Vasya Pupkin、25歳

これは名前付き引数を渡すのと非常に似ていますが、唯一の違いは、メソッドに辞書を渡すことです。 リストを渡す前に1つのアスタリスク「*」を指定した場合、辞書を渡す前に、format()メソッドの引数の前に2つのアスタリスク「**」を置き、文字列の中括弧内に参照します。渡された辞書のキーにそれらの値を展開するために..。

format()メソッドを使用して文字列内の変数を展開するためのすべてのオプションについて説明しました。 将来的には、フォーマット演算子T.K.の代わりにこの方法を使用することを強くお勧めします。 この方法はより新しく、より柔軟であり、公式の情報源はこの方法に固執することを勧めています。

Format()メソッド(オプション)

次に、format()文字列メソッドの追加機能を紹介します。 に関するより広範な情報 この方法、habrに関する記事、または公式のPythonドキュメントをご覧ください。

注意! 残りはformat()メソッドに関する記事の断片です。

もう一度簡単なものから始めましょう。指定された長さの文字列を出力する必要がある場合は、コロン(:)を追加し、変数名の後に文字数を追加します。 したがって、私の名前を印刷して、スペースを入れて10文字に埋め込むには、次のようにする必要があります。

>>>「あなたの名前は(name:10)」です。形式(name = "Reuven")

「あなたの名前はルーベンです」

(行には名前の後にスペースが埋め込まれていることに注意してください。)

ブロックの右側に配置を設定する必要がある場合は、:と数字の間に>記号を使用します。

>>>「あなたの名前は(name:> 10)」です。形式(name = "Reuven")

「あなたの名前はルーベンです」

そして、はい、あなたは私が記号を使って左寄せしたいことを明示的に示すことができます<

ブロックの中央に値を表示する必要がある場合は、代わりに< и >記号^が使用されます:

>>>「あなたの名前は(name:* ^ 10)」です。形式(name = "Reuven")

「あなたの名前は** Reuven **です」

テキストは多かれ少なかれ明確ですが、数字はどうですか? 個人的には、これがどのように機能するかを想像するのは困難でしたが、すべてが非常に簡単であることがわかりました。 にとって 簡単な撤退数値は文字列と同様の構文を使用します。

>>>「価格は$(数値)です。」フォーマット(数値= 123)

これまで、2つの出力方法を使用してきました:式の値をインタラクティブに出力する方法とprintステートメントを使用する方法です(3番目の方法はファイルオブジェクトのwrite()メソッドです)。

スペースで区切られた値を出力するだけでなく、出力のフォーマットをより細かく制御したいという要望がよくあります。 もちろん、文字列を自分で操作することもできます。スライスおよびマージ操作を使用して、想像できる任意の配置を作成できます。 行には、列1の必要な幅までスペースを埋めるためのメソッドがあります。 もう1つの方法は、左の引数として文字列を指定して%演算子を使用することです。 %演算子は、右側の文字列を、右側の引数に適用されるC sprintf()スタイルのフォーマット文字列として解釈し、フォーマットされた文字列を返します。

もちろん、もう1つの質問が残っています:さまざまなタイプの値の文字列表現を取得する方法は? 幸い、Pythonには、str()関数を使用して任意の値を文字列に変換する機能があります。 実際、この言語は、文字列表現を取得するための2つの関数repr()(式をバッククォートで囲むだけで同じ効果を得ることができます: `expr`)とstr()を提供します。 たとえば、最初のメソッドは、インタプリタがインタラクティブモードで式の値を出力するために使用され、2番目のメソッドはprintステートメントで引数を出力するために使用されます。 str()関数は、可能であれば出力に最適な表現を返し、repr()関数は式の対話型入力を返します。 ここではいくつかの例を示します。

>>> x = 10 * 3.14

数値31.4は、2進数で正確に表すことはできないため、次のようになります。

>>> x
31.400000000000002

ただし、str()関数は、妥当な精度で数値を出力します。

>>> y = 200 * 200
>>> s = "xの値は" + str(x)+ \
... "、yの値は" + str(y)+ "..."です。
>>>印刷s
x値は31.4、y値は40,000..。

長整数は、「L」サフィックスを付けてPythonで記述されます。 バージョン1.6以降、str()関数はそれを出力しません。

>>> repr(1000L)
「1000L」
>>> str(1000L)
"1000"

文字列表現は、他のタイプでも取得できます。

>>> p =
>>> ps = repr(p)
>>> ps
""
>>> `x、y、("スパム "、"卵 ")`
"(31.400000000000002、40000、("スパム "、"卵 "))"

repr()(または '')関数は、引用符を追加し、エスケープシーケンスを使用して特殊文字を書き込みます。

>>> hello = "hello、world \ n"
>>>こんにちはを印刷
こんにちは世界

>>> hellos = `hello`
>>>こんにちはを印刷
「こんにちは、世界\ n」

正方形と立方体のテーブルを2つの説明された方法で表示してみましょう。

>>>範囲(1、11)のxの場合:
...印刷str(x).rjust(2)、str(x * x).rjust(3)、
...#末尾のコンマに注意してください
... print str(x * x * x).rjust(4)
...
1 1 1
2 4 8
3 9 27
4 16 64
5 25 125
6 36 216
7 49 343
8 64 512
9 81 729
10 100 1000

>>>範囲(1,11)のxの場合:
... print "%2d%3d%4d"%(x、x * x、x * x * x)
...
1 1 1
2 4 8
3 9 27
4 16 64
5 25 125
6 36 216
7 49 343
8 64 512
9 81 729
10 100 1000

(列の間に1つのスペースがprintステートメントによって追加されたことに注意してください。)

この例は、文字列のrjust()メソッドの使用法を示しています。このメソッドは、指定された幅のフィールドで文字列を右に揃え、左側にスペースを埋め込みます。 ljust()メソッドとcenter()メソッドは同じように機能します。 何も出力しません。新しい行を返すだけです。 元の文字列が長すぎる場合、切り捨てられませんが、変更されずに返されます。通常、間違った値を出力するよりも、列のレイアウトを台無しにする方が適切です。 (本当にトリミングしたい場合は、スライス操作「s.ljust(n)」を使用してください。)

文字列モジュールで定義されているzfill()関数も便利です。この関数は、文字列に左からの数字をゼロで埋め、プラス記号とマイナス記号を正しく処理します。

>>>インポート文字列
>>> string.zfill( "12"、5)
"00012"
>>> string.zfill( "-3.14"、7)
"-003.14"
>>> string.zfill( "3.14159265359"、5)
"3.14159265359"

%演算子の使用は次のようになります。

>>>数学をインポートする
>>> print "PI値は約%5.3fです。" %\
... math.pi
PI値は約3.142です。

文字列に複数の値を表示する必要がある場合は、タプルが右のオペランドとして使用されます:

>>>テーブル=( "Sjoerd":4127、 "Jack":4098、 "Dcab":7678)
>>>名前については、table.items()の電話番号:
... print "%-10s ==>%10d"%(名前、電話)
...
Dcab ==> 7678
ジャック==> 4098
Sjoerd ==> 4127

ほとんどの形式はCとまったく同じように機能します。ただし、引数の型が形式と一致しない場合、インタープリターはそれらを必要な型にキャストします(たとえば、任意の型の式は、 str()組み込み関数)または、不可能な場合は、例外2をスローします。 *を使用して、フィールド幅または精度を個別のパラメーターとして渡すことができます。

正しい引数がタプルの場合、 いつも引数リストと見なされます:

>>> def f(x):
... print "値 '%s'が関数に渡されました"%x
...
>>> f(1)

>>> f()

>>>#は期待どおりに解釈されません
... f((1、))
関数に値「1」が渡されました
>>>#エラー
... f((1、2))
トレースバック(最後の最後の呼び出し):
ファイル " "、2行目、
ファイル " "、2行目、f
TypeError:文字列のフォーマット中にすべての引数が変換されるわけではありません

V この場合 1つの要素で構成されるタプルを右のオペランドとして使用する方が安全です。

>>> def f(x):
... print "値が関数に渡されました"%s ""%(x、)
...
>>>#これですべてが正しい
... f((1、))
関数に値「(1、)」が渡されました
>>> f((1、2))
関数に値「(1、2)」が渡されました
>>> f(1)
関数に値「1」が渡されました
>>> f()
関数に値「」が渡されました

長い形式の文字列の場合、位置ではなく名前で変数を参照することをお勧めします。 これは、拡張された%(名前)形式の表記法を使用して実行できます。次に例を示します。

>>>テーブル=( "Sjoerd":4127、 "Jack":4098、 "Dcab":8637678)
>>> print "Jack:%(Jack)d; Sjoerd:%(Sjoerd)d; Dcab:%(Dcab)d"%table
ジャック:4098; Sjoerd:4127; Dcab:8637678

これは、現在のスコープ内の変数のディクショナリを返す組み込みのvars()関数と組み合わせると特に便利です。

  • 翻訳

私はHabraの読者とPythonファンの注意を引き、文字列のフォーマットに関するかなり長い記事の翻訳を紹介します。 物語は真実であり、習慣が頑固に抵抗したとしても、保守派が時々何か新しいことを考えるべきであることをほのめかします。

会話のトピックではない質問をする傾向がある読者の好奇心を予想して、私は絵が最も楽しいものではありませんが、間接的にPythonに関連していると言います。 宿題としてその理由を見つけることをお勧めします。

私は、個人的なデザインの誤りやタイプミスについてのコメントを待っています-私からの伝統的なhabraplyushki。

私は何年もの間Pythonで書いています。 しかし、この旅の最初の頃、​​私は文字列をPerlスタイルでフォーマットする方法を知りたいと思っていました。 Perl(および多くの通訳者)を思い出させてください コマンドライン Unixの場合)2種類の文字列リテラルをサポートします- 一重引用符(行がそのまま表示される場合)、変数の代わりにそれらの値が置き換えられる場所で2倍になります。 たとえば、Perlでは、次のように書くことができます。

$ name = "Reuven"; print "Hello、$ name \ n";
したがって、プログラムは「Hello、Reuven」と記述します。

Pythonの文字列リテラルは引用符のタイプに依存せず、その中の変数が値に展開されることはありません。 これを実現するために、%演算子は従来から文字列で使用されてきました。 このコンテキストでは、オペレーターは左側の行を見て、右側の対応する変数の値で置き換える必要のある値の数を数えます。 操作の結果は、プレースホルダーの代わりに変数の値が挿入された新しい行になります。 例えば:

>>> name = "Reuven" >>> "Hello、%s"%name "Hello、Reuven"
このPythonコードはそれ自体で正常に機能し、パーソナライズされた挨拶を表示します。 したがって、Pythonでの長年の練習にもかかわらず、この構文の使用には非常に満足していました。 はい、それはあまり良くありません。いいえ、フォーマットに影響を与える多数のprintf修飾子をメモリに保持したことはありません。 つまり、私は常に「s」修飾子(文字列として出力)を使用しており、Pythonが暗黙的に引数を文字列にキャストするだけで十分でした。

しかし、現時点では、%構文が廃止されているか、少なくとも非推奨になっているのは事実です。 python-devメーリングリストには、2.xブランチでは少なくとも2022年まで存続するという注記がありますが、3.xブランチについては何も述べられていないため、この構文のサポートはまもなく削除され、それを使用することが望ましい。 str.formatメソッドに置き換えられました。

私のPythonチュートリアルでは、常にstr.formatについて言及しましたが、 具体例多くの場合、すべて同じものが%に依存していました。 個人的にははるかに簡単に思えたので、生徒に%を使用することをお勧めしました。

しかし、私が何か間違ったことをしているという永続的な感覚、そしておそらく私の学生を誤解させることさえ、私にstr.formatをより綿密に研究するように促しました。 調査中に、次の結論に達しました。1)%よりも複雑ではなく、一部のアプリケーションではさらに単純です。 2)str.formatの機能を最大限に活用したことはなく、習得に時間がかかるにもかかわらず、非常に便利です。

最も単純なものから始めましょう。 誰かに「おはよう」と言ってみましょう。変数「first」と「last」に格納されていると仮定して、名前と名前で呼びかけます。 古い方法では、これを行います。

>>> first = "Reuven" >>> last = "Lerner" >>> "おはよう、%s%s"%(first、last) "おはよう、Reuven Lerner"
この例でも、%構文の問題の1つに直面しています。2つの変数があり、両方を使用するには、それらのタプルを作成する必要があります。 Pythonの観点からは、これは論理的ですが、多くの学生がこれに非常に驚いていることは間違いありません。

str.formatの場合、この例はどのようになりますか? かなり似ています:

>>>「おはようございます、()()」。フォーマット(最初、最後)「おはようございます、ルーヴェン・ラーナー」
原則を少し変更しましたのでご注意ください。 今ではありません 二項演算子文字列の上にあり、objectメソッドはいくつかのパラメータをとる文字列です。 これは論理的で、より一貫性があります。 それらの同じ学生にとって、私の例の%演算子は、文字列に対する操作ではなく、印刷への追加のように見えました。 行の後の「.format」表記は、これがその特定の行を参照するメソッドであることをより明確にします。

おそらくすでにご存知のように、文字列に「()()」が含まれている場合、str.formatは2つのパラメーターを受け取る必要があり、その値はメソッドに渡される順序で文字列に挿入されます。 。 引数は2つあるため、文字列には()が2つ含まれている必要があります。 Pythonの中括弧は人々に辞書を示唆し、空の括弧はあまり見栄えが良くないため、これを理解するのは少し難しいです。 しかし、それは大丈夫です、私はそれと一緒に暮らすことができて、それを非常に簡単に受け入れました。

str.formatが%よりも最初の利点を示すポイントは、でパラメーターを使用する必要がある場合です。 逆順..。 実際、%sでこれを達成する方法はありません。 また、1つの変数の値を複数回再利用することもできません。 str.formatを使用すると、置換シーケンスを簡単に変更できます。

>>>「おはようございます、(1)(0)」。フォーマット(最初、最後)「おはようございます、ラーナー・ルーヴェン」
空の角かっこ「()()」を使用した場合、パラメーターがメソッドに渡されるのと同じ順序で置換が行われることに注意してください。 パラメータは最初からインデックスが付けられたシーケンスと考えることができます。順序を変更したい場合は、このシーケンスの必要なインデックスを中かっこで囲んでください。 str.formatを使用した最初の例は、次のように記述できます。

>>>「おはようございます、(0)(1)」。フォーマット(最初、最後)「おはようございます、ルーヴェン・ラーナー」
インデックスを明示的に指定することにより、自動インデックス付けに依存できなくなることに注意してください。

もちろん、*演算子を使用してリストからシーケンスを使用することもできます。

>>> names =( "Reuven"、 "Lerner")>>> "おはよう、()()"。format(* names) "おはよう、Reuven Lerner"
名前付き引数を使用することもできます。

>>>「おはよう、(最初)(最後)」。フォーマット(最初=「ルーヴェン」、最後=「ラーナー」)「おはよう、ルーヴェン・ラーナー」
私は特にこのオプションが好きです。 名前付きパラメーターはより明示的です( 良い名前)、および(first)と(last)の使用は非常に読みやすく、特に%(first)sと比較すると、%演算子で必要になります。

名前付きパラメーターは、**演算子を使用して辞書から展開することもできます。

>>> person =( "first": "Reuven"、 "last": "Lerner")>>> "おはよう、(最初)(最後)"。format(** person) "おはよう、Reuven Lerner"
私はこれらすべてを生徒に説明しましたが、この構文で生徒がどれほど快適に生活できるかに非常に驚いていました。 そして、自分で仕事をすることがより楽しくなりました。

名前付き引数と位置引数は、技術的には一緒に使用できることに注意してください。 ただし、これは行わない方がよいでしょう。

>>> person =( "first": "Reuven"、 "last": "Lerner")>>> "Good(0)、(first)(last)"。format( "morning"、** person) "おはようございます、ルーヴェン・ラーナー」

私は警告した。

str.formatに欠けているのは、... um ...フォーマットです。 悪いニュースは、str.formatには、出力のフォーマット方法を決定するためのまったく異なるルールがあることです。 良いニュースは、これらのルールはかなり簡単に習得して理解できることです。

もう一度簡単なものから始めましょう。指定された長さの文字列を出力する必要がある場合は、コロン(:)を追加し、変数名の後に文字数を追加します。 したがって、私の名前を印刷して、スペースを入れて10文字に埋め込むには、次のようにする必要があります。

>>>「あなたの名前は(name:10)」です。形式(name = "Reuven") "あなたの名前はReuvenです"
(行には名前の後にスペースが埋め込まれていることに注意してください。)

ブロックの右側に配置を設定する必要がある場合は、:と数字の間に>記号を使用します。

>>> "あなたの名前は(name:> 10)"。形式(name = "Reuven") "あなたの名前はReuven"
そして、はい、あなたは私が記号を使って左寄せしたいことを明示的に示すことができます<
ブロックの中央に値を表示する必要がある場合は、代わりに< и >記号^が使用されます:

>>> "あなたの名前は(name:* ^ 10)"。形式(name = "Reuven") "あなたの名前は** Reuven **"
テキストは多かれ少なかれ明確ですが、数字はどうですか? 個人的には、これがどのように機能するかを想像するのは困難でしたが、すべてが非常に簡単であることがわかりました。 数値を簡単に表示するには、文字列に似た構文を使用します。

>>>「価格は$(数値)です。」フォーマット(数値= 123)「価格は$ 123です。」
しかし、数字にはそれが適用されます 大量文字列よりも修飾子。 たとえば、数値を2進数で表示するには、「b」修飾子を追加します。16進数の場合は、「x」修飾子を追加します。

>>>「価格は$(数値:b)です。」。形式(数値= 5)「価格は$ 101です。」 >>>「価格は$(数値:x)です。」。形式(数値= 123)「価格は$ 70億です。」
もちろん、数字は先行ゼロで書くことができます:

>>>「あなたの電話は私たちにとって重要です。あなたは電話番号(番号:05)です。」フォーマット(番号= 123)「あなたの電話は私たちにとって重要です。あなたは電話番号00123です。」
実行可能なPythonコードは()内では使用できないことに注意してください。代わりに、Python全体とは別の、異なる単純なマイクロ言語が提供されます。 マイナーな例外もあります。 まず、ドットを介して属性/プロパティの値を取得できます。次に、を使用してインデックスによってオブジェクトの値を取得できます。

例えば:

>>> class Foo(object):def __init __(self):self.x = 100 >>> f = Foo()>>> "Your number is(ox)" .format(o = f) "Your number 100 "nです
「f」オブジェクトの「x」属性を取得しました。 このオブジェクトには、文字列内の「o」という名前でアクセスできます。 属性を取得することはできますが、実行することはできません。

>>> "あなたの名前は(name.upper())"です。Format(name = "Reuven")AttributeError: "str"オブジェクトには属性 "upper()"がありません
適切なメソッドが呼び出されることを想定して「name.upper()」を実行しようとしましたが、Pythonはこの時点でコードの実行を許可せず、「upper()」を括弧とともに属性として扱います。 括弧なしでは、関数/メソッドの文字列表現を取得するだけです。

>>> "あなたの名前は(name.upper)"です。フォーマット(name = "Reuven") "あなたの名前は "
角かっこを使用すると、反復可能なオブジェクト(リスト、文字列)の要素をインデックスで取得できます。 ただし、スライス操作はサポートされていません。

>>>「あなたの好きな数字は(n)です。」。フォーマット(n =数字)「あなたの好きな数字は3です。」
しかし:

>>>「お気に入りの数字は(n)です。」。フォーマット(n =数字)ValueError:フォーマット文字列に「]」がありません
また、名前で辞書のエントリを取得するために使用することもできますが、名前は引用符なしで入力されます。

>>> person =( "first": "Reuven"、 "last": "Lerner")>>> "あなたの名前は(p)です。"。format(p = person) "あなたの名前はReuvenです。"
引用符を使用しようとすると、例外が発生します...

>>> "あなたの名前は(p [" first "])。"。Format(p = person)KeyError: "" first ""
str.formatのすべてのユースケースがここに示されているわけではありません。実際、各タイプのフォーマット規則の仕様があります。 たとえば、浮動小数点数の精度オプションは文字列では使用できません。

クラス内のオブジェクトに独自のフォーマットルールを追加して、オブジェクトをカスタマイズするための特別な表示方法と修飾子を使用することもできます。

このトピックをさらに詳しく調べたい場合は、str.formatについて説明しているPEP3101から始める必要があります。 このトピックに関するかなり良い要約を含むEricSmithのプレゼンテーションをお勧めすることもできます。 有る 良い例 Pythonドキュメントで%の使用からstr.formatに移行する方法

楽しんでください!

最近、ブログが「Pythonで%sは何を意味するのか」というクエリで見つかることがあることがわかりました。 私は自分自身を覚えています-Pythonを学び始めたとき、私は迅速で理解しやすい答えが欲しかったのです(彼らは「頭を騙さないで、指を見せて」と言います)。 せっかちな人のために、この記事。

目次

まず、いくつかの例

文字列のフォーマット:
>>> name = "Vasya" >>> print "My name is%s"%(name)My name is Vasyaフィールドのサイズを示します( "Vasya"の前に5つのスペース、つまり合計10文字があります) ):> >> print "私の名前は%10sです。それは私の名前です。"%(名前)私の名前はVasyaです。それは私の名前です。 同じですが、左揃えです:>>> print "私の名前は%-10sです。それは私の名前です。"%(名前)私の名前はVasyaです。それは私の名前です。 これが役立つ場合:>>> drink =( "Long Island":3、 "Bloody Mary":2、 "Margarita":4)>>> print "%-15s%-5s"%( "Name"、 "数量")名前数量>>> k、vの場合 in drinks.items():... print "%-15s%-3s"%(k、v)...ブラッディマリー2ロングアイランド3マルガリータ4数値の整数部分を印刷する必要がある場合:
>>> num = 12.34 >>> print "%d"%(num)12混合:
>>>年齢= 25 >>> print "私の名前は%s。I" m%d。 "%(名前、年齢)私の名前はVasyaです。I" m25。

さて、一言で言えば、%演算子がどのように機能するか

フォーマット式は、大きく3つの部分に分けることができます。

Format_definition +%+オブジェクト(s)

記号%s、%d、%gなどは、データ型の形式です。 C言語に精通している場合、これはprintf()が印刷に使用する構文と同じです。

仕様 他の種類 Pythonデータを次の表に示します。

フォーマット 意味
「d」 10進数の整数。
"私" 10進数の整数。
「o」 8進数。
「u」 廃止されたタイプは「d」と同じです。
"バツ" 16進数(小文字)。
"バツ" 16進数(大文字)。
「e」 指数形式の実数(小文字)。
「E」 指数形式の実数(大文字)。
「f」
「F」 10進数形式の実数。
「g」 実数。 小文字の「f」または「e」の形式を使用します。
「G」 実数。 大文字の「F」または「E」形式を使用します。
「c」 1文字(または数字)。
「r」 repr()。
「s」 str()を使用してPythonオブジェクトが変換される文字列。
"%" 引数は変換されず、「%」文字のみが出力されます。

format()組み込み関数

これは次のように機能します:str.format()

文字列では、「置換フィールド」は中括弧()で囲まれています。 角かっこで囲まれていないものはすべて通常のテキストとして扱われ、変更されずにコピーされます。 テキストで中括弧文字を渡すために、それらは複製されます:((および))。
置換フィールドの形式は次のとおりです。

Replace_field :: = "(" [field_name] ["!" Conversion] [":" Specification] ")" field_name :: = arg_name( "。" Attribute_name | "[" item_number "]")* arg_name :: = [識別子| integer] attribute_name :: = id item_index :: = integer | 文字列インデックスstring_index :: =<любой символ кроме "]">+変換:: = "r" | "s" #strまたはrepr仕様:: =<описано ниже>どこ
仕様:: = [[スタブ]配置] [記号] [#] [幅] [、] [。精度] [タイプ]スタブ:: =<любой символ>アラインメント:: = "<" | ">"|" = "|" ^ "sign :: =" + "|"-"|" "width :: = integer#フィールド幅の精度:: = integer#小数点以下の桁数type :: =" b "|" c " | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | " % "このように書かれています:>>> print" "" \ n(0)...壁に座っています...(0)...眠りに落ちました。 "" "。形式("ハンプティダンプティ ")ハンプティ・ダンプティ壁に座ったハンプティ・ダンプティ夢の中で落ちた。

ご覧のとおり、このメソッドは「%」演算子よりもはるかに柔軟性があります。これは、同じ値を任意の順序で再利用できるためです。 名前付き引数を渡すこともできます。そうすれば、数字ではなく名前でそれらを参照します。

フォーマットの別の例:

>>> toc =(...( "第1章"、 "3")、...( "第2章"、 "150")...)>>> tocの行:... print( "(:。
  • 翻訳

私はHabraの読者とPythonファンの注意を引き、文字列のフォーマットに関するかなり長い記事の翻訳を紹介します。 物語は真実であり、習慣が頑固に抵抗したとしても、保守派が時々何か新しいことを考えるべきであることをほのめかします。

会話のトピックではない質問をする傾向がある読者の好奇心を予想して、私は絵が最も楽しいものではありませんが、間接的にPythonに関連していると言います。 宿題としてその理由を見つけることをお勧めします。

私は、個人的なデザインの誤りやタイプミスについてのコメントを待っています-私からの伝統的なhabraplyushki。

私は何年もの間Pythonで書いています。 しかし、この旅の最初の頃、​​私は文字列をPerlスタイルでフォーマットする方法を知りたいと思っていました。 Perl(およびUnixの多くのコマンドラインインタープリター)は、2種類の文字列リテラルをサポートしていることを思い出してください。一重引用符(文字列がそのまま出力される場合)と、変数が値に置き換えられる二重引用符です。 たとえば、Perlでは、次のように書くことができます。

$ name = "Reuven"; print "Hello、$ name \ n";
したがって、プログラムは「Hello、Reuven」と記述します。

Pythonの文字列リテラルは引用符のタイプに依存せず、その中の変数が値に展開されることはありません。 これを実現するために、%演算子は従来から文字列で使用されてきました。 このコンテキストでは、オペレーターは左側の行を見て、右側の対応する変数の値で置き換える必要のある値の数を数えます。 操作の結果は、プレースホルダーの代わりに変数の値が挿入された新しい行になります。 例えば:

>>> name = "Reuven" >>> "Hello、%s"%name "Hello、Reuven"
このPythonコードはそれ自体で正常に機能し、パーソナライズされた挨拶を表示します。 したがって、Pythonでの長年の練習にもかかわらず、この構文の使用には非常に満足していました。 はい、それはあまり良くありません。いいえ、フォーマットに影響を与える多数のprintf修飾子をメモリに保持したことはありません。 つまり、私は常に「s」修飾子(文字列として出力)を使用しており、Pythonが暗黙的に引数を文字列にキャストするだけで十分でした。

しかし、現時点では、%構文が廃止されているか、少なくとも非推奨になっているのは事実です。 python-devメーリングリストには、2.xブランチでは少なくとも2022年まで存続するという注記がありますが、3.xブランチについては何も述べられていないため、この構文のサポートはまもなく削除され、それを使用することが望ましい。 str.formatメソッドに置き換えられました。

私のPythonチュートリアルでは、常にstr.formatについて言及しましたが、特定の例では、%に依存することがよくありました。 個人的にははるかに簡単に思えたので、生徒に%を使用することをお勧めしました。

しかし、私が何か間違ったことをしているという永続的な感覚、そしておそらく私の学生を誤解させることさえ、私にstr.formatをより綿密に研究するように促しました。 調査中に、次の結論に達しました。1)%よりも複雑ではなく、一部のアプリケーションではさらに単純です。 2)str.formatの機能を最大限に活用したことはなく、習得に時間がかかるにもかかわらず、非常に便利です。

最も単純なものから始めましょう。 誰かに「おはよう」と言ってみましょう。変数「first」と「last」に格納されていると仮定して、名前と名前で呼びかけます。 古い方法では、これを行います。

>>> first = "Reuven" >>> last = "Lerner" >>> "おはよう、%s%s"%(first、last) "おはよう、Reuven Lerner"
この例でも、%構文の問題の1つに直面しています。2つの変数があり、両方を使用するには、それらのタプルを作成する必要があります。 Pythonの観点からは、これは論理的ですが、多くの学生がこれに非常に驚いていることは間違いありません。

str.formatの場合、この例はどのようになりますか? かなり似ています:

>>>「おはようございます、()()」。フォーマット(最初、最後)「おはようございます、ルーヴェン・ラーナー」
原則を少し変更しましたのでご注意ください。 現在、これは文字列に対する二項演算子ではなく、いくつかのパラメーターを受け取る文字列オブジェクトのメソッドです。 これは論理的で、より一貫性があります。 それらの同じ学生にとって、私の例の%演算子は、文字列に対する操作ではなく、印刷への追加のように見えました。 行の後の「.format」表記は、これがその特定の行を参照するメソッドであることをより明確にします。

おそらくすでにご存知のように、文字列に「()()」が含まれている場合、str.formatは2つのパラメーターを受け取る必要があり、その値はメソッドに渡される順序で文字列に挿入されます。 。 引数は2つあるため、文字列には()が2つ含まれている必要があります。 Pythonの中括弧は人々に辞書を示唆し、空の括弧はあまり見栄えが良くないため、これを理解するのは少し難しいです。 しかし、それは大丈夫です、私はそれと一緒に暮らすことができて、それを非常に簡単に受け入れました。

str.formatが%よりも最初の利点を示すポイントは、パラメーターを逆の順序で使用する必要がある場合です。 実際、%sでこれを達成する方法はありません。 また、1つの変数の値を複数回再利用することもできません。 str.formatを使用すると、置換シーケンスを簡単に変更できます。

>>>「おはようございます、(1)(0)」。フォーマット(最初、最後)「おはようございます、ラーナー・ルーヴェン」
空の角かっこ「()()」を使用した場合、パラメーターがメソッドに渡されるのと同じ順序で置換が行われることに注意してください。 パラメータは最初からインデックスが付けられたシーケンスと考えることができます。順序を変更したい場合は、このシーケンスの必要なインデックスを中かっこで囲んでください。 str.formatを使用した最初の例は、次のように記述できます。

>>>「おはようございます、(0)(1)」。フォーマット(最初、最後)「おはようございます、ルーヴェン・ラーナー」
インデックスを明示的に指定することにより、自動インデックス付けに依存できなくなることに注意してください。

もちろん、*演算子を使用してリストからシーケンスを使用することもできます。

>>> names =( "Reuven"、 "Lerner")>>> "おはよう、()()"。format(* names) "おはよう、Reuven Lerner"
名前付き引数を使用することもできます。

>>>「おはよう、(最初)(最後)」。フォーマット(最初=「ルーヴェン」、最後=「ラーナー」)「おはよう、ルーヴェン・ラーナー」
私は特にこのオプションが好きです。 名前付きパラメーターはより明確であり(適切な名前がある場合)、(最初の)および(最後の)の使用は非常に読みやすくなります-特に%演算子で必要な%(最初の)と比較して

名前付きパラメーターは、**演算子を使用して辞書から展開することもできます。

>>> person =( "first": "Reuven"、 "last": "Lerner")>>> "おはよう、(最初)(最後)"。format(** person) "おはよう、Reuven Lerner"
私はこれらすべてを生徒に説明しましたが、この構文で生徒がどれほど快適に生活できるかに非常に驚いていました。 そして、自分で仕事をすることがより楽しくなりました。

名前付き引数と位置引数は、技術的には一緒に使用できることに注意してください。 ただし、これは行わない方がよいでしょう。

>>> person =( "first": "Reuven"、 "last": "Lerner")>>> "Good(0)、(first)(last)"。format( "morning"、** person) "おはようございます、ルーヴェン・ラーナー」

私は警告した。

str.formatに欠けているのは、... um ...フォーマットです。 悪いニュースは、str.formatには、出力のフォーマット方法を決定するためのまったく異なるルールがあることです。 良いニュースは、これらのルールはかなり簡単に習得して理解できることです。

もう一度簡単なものから始めましょう。指定された長さの文字列を出力する必要がある場合は、コロン(:)を追加し、変数名の後に文字数を追加します。 したがって、私の名前を印刷して、スペースを入れて10文字に埋め込むには、次のようにする必要があります。

>>>「あなたの名前は(name:10)」です。形式(name = "Reuven") "あなたの名前はReuvenです"
(行には名前の後にスペースが埋め込まれていることに注意してください。)

ブロックの右側に配置を設定する必要がある場合は、:と数字の間に>記号を使用します。

>>> "あなたの名前は(name:> 10)"。形式(name = "Reuven") "あなたの名前はReuven"
そして、はい、あなたは私が記号を使って左寄せしたいことを明示的に示すことができます<
ブロックの中央に値を表示する必要がある場合は、代わりに< и >記号^が使用されます:

>>> "あなたの名前は(name:* ^ 10)"。形式(name = "Reuven") "あなたの名前は** Reuven **"
テキストは多かれ少なかれ明確ですが、数字はどうですか? 個人的には、これがどのように機能するかを想像するのは困難でしたが、すべてが非常に簡単であることがわかりました。 数値を簡単に表示するには、文字列に似た構文を使用します。

>>>「価格は$(数値)です。」フォーマット(数値= 123)「価格は$ 123です。」
ただし、文字列よりも数値の方が多くの修飾子があります。 たとえば、数値を2進数で表示するには、「b」修飾子を追加します。16進数の場合は、「x」修飾子を追加します。

>>>「価格は$(数値:b)です。」。形式(数値= 5)「価格は$ 101です。」 >>>「価格は$(数値:x)です。」。形式(数値= 123)「価格は$ 70億です。」
もちろん、数字は先行ゼロで書くことができます:

>>>「あなたの電話は私たちにとって重要です。あなたは電話番号(番号:05)です。」フォーマット(番号= 123)「あなたの電話は私たちにとって重要です。あなたは電話番号00123です。」
実行可能なPythonコードは()内では使用できないことに注意してください。代わりに、Python全体とは別の、異なる単純なマイクロ言語が提供されます。 マイナーな例外もあります。 まず、ドットを介して属性/プロパティの値を取得できます。次に、を使用してインデックスによってオブジェクトの値を取得できます。

例えば:

>>> class Foo(object):def __init __(self):self.x = 100 >>> f = Foo()>>> "Your number is(ox)" .format(o = f) "Your number 100 "nです
「f」オブジェクトの「x」属性を取得しました。 このオブジェクトには、文字列内の「o」という名前でアクセスできます。 属性を取得することはできますが、実行することはできません。

>>> "あなたの名前は(name.upper())"です。Format(name = "Reuven")AttributeError: "str"オブジェクトには属性 "upper()"がありません
適切なメソッドが呼び出されることを想定して「name.upper()」を実行しようとしましたが、Pythonはこの時点でコードの実行を許可せず、「upper()」を括弧とともに属性として扱います。 括弧なしでは、関数/メソッドの文字列表現を取得するだけです。

>>> "あなたの名前は(name.upper)"です。フォーマット(name = "Reuven") "あなたの名前は "
角かっこを使用すると、反復可能なオブジェクト(リスト、文字列)の要素をインデックスで取得できます。 ただし、スライス操作はサポートされていません。

>>>「あなたの好きな数字は(n)です。」。フォーマット(n =数字)「あなたの好きな数字は3です。」
しかし:

>>>「お気に入りの数字は(n)です。」。フォーマット(n =数字)ValueError:フォーマット文字列に「]」がありません
また、名前で辞書のエントリを取得するために使用することもできますが、名前は引用符なしで入力されます。

>>> person =( "first": "Reuven"、 "last": "Lerner")>>> "あなたの名前は(p)です。"。format(p = person) "あなたの名前はReuvenです。"
引用符を使用しようとすると、例外が発生します...

>>> "あなたの名前は(p [" first "])。"。Format(p = person)KeyError: "" first ""
str.formatのすべてのユースケースがここに示されているわけではありません。実際、各タイプのフォーマット規則の仕様があります。 たとえば、浮動小数点数の精度オプションは文字列では使用できません。

クラス内のオブジェクトに独自のフォーマットルールを追加して、オブジェクトをカスタマイズするための特別な表示方法と修飾子を使用することもできます。

このトピックをさらに詳しく調べたい場合は、str.formatについて説明しているPEP3101から始める必要があります。 このトピックに関するかなり良い要約を含むEricSmithのプレゼンテーションをお勧めすることもできます。 Pythonのドキュメントには、%の使用からstr.formatへの移行方法に関する良い例もあります。

楽しんでください!

トピックの続き:
アップル

TTKは、1997年に事業を開始し、電気通信の分野でサービスを提供している有名な会社です。 組織の本部はモスクワにあり、...