2. 字句解析—Pythonドキュメント

提供:Dev Guides
< PythonPython/docs/3.9/reference/lexical analysis
移動先:案内検索

2.2。 字句解析

Pythonプログラムは、パーサーによって読み取られます。 パーサーへの入力は、字句解析プログラムによって生成されたトークンのストリームです。 この章では、字句解析プログラムがファイルをトークンに分割する方法について説明します。

PythonはプログラムテキストをUnicodeコードポイントとして読み取ります。 ソースファイルのエンコーディングは、エンコーディング宣言によって指定でき、デフォルトはUTF-8です。詳細については、 PEP 3120 を参照してください。 ソースファイルをデコードできない場合は、 SyntaxError が発生します。

2.1。 線の構造

Pythonプログラムは、いくつかの論理行に分割されています。

2.1.1。 論理行

論理行の終わりは、トークンNEWLINEで表されます。 ステートメントは、NEWLINEが構文で許可されている場合を除いて、論理行の境界を越えることはできません(たとえば、複合ステートメント内のステートメント間)。 論理ラインは、明示的または暗黙的なライン結合ルールに従って、1つ以上の物理ラインから構築されます。


2.1.2。 物理的な線

物理行は、行末シーケンスで終了する文字のシーケンスです。 ソースファイルと文字列では、標準のプラットフォーム行終了シーケンスのいずれかを使用できます-ASCII LF(改行)を使用するUnixフォーム、ASCIIシーケンスCR LF(リターンの後に改行)を使用するWindowsフォーム、またはを使用する古いMacintoshフォームASCII CR(リターン)文字。 プラットフォームに関係なく、これらのフォームはすべて等しく使用できます。 入力の終わりは、最終的な物理行の暗黙的なターミネータとしても機能します。

Pythonを埋め込む場合、改行文字の標準C規則を使用してソースコード文字列をPython APIに渡す必要があります(ASCIILFを表す\n文字は行末記号です)。


2.1.3。 コメント

コメントは、文字列リテラルの一部ではないハッシュ文字(#)で始まり、物理行の終わりで終わります。 コメントは、暗黙の行結合ルールが呼び出されない限り、論理行の終わりを示します。 コメントは構文によって無視されます。


2.1.4。 エンコーディング宣言

Pythonスクリプトの1行目または2行目のコメントが正規表現coding[=:]\s*([-\w.]+)と一致する場合、このコメントはエンコード宣言として処理されます。 この式の最初のグループは、ソースコードファイルのエンコーディングに名前を付けます。 エンコーディング宣言は、独自の行に表示する必要があります。 2行目である場合、最初の行もコメントのみの行である必要があります。 エンコード式の推奨される形式は次のとおりです。

# -*- coding: <encoding-name> -*-

これはGNUEmacsでも認識されています。

# vim:fileencoding=<encoding-name>

これはBramMoolenaarのVIMによって認識されます。

エンコーディング宣言が見つからない場合、デフォルトのエンコーディングはUTF-8です。 さらに、ファイルの最初のバイトがUTF-8バイト順マーク(b'\xef\xbb\xbf')の場合、宣言されたファイルエンコーディングはUTF-8です(これは、特にMicrosoftのメモ帳でサポートされています)。 )。

エンコーディングが宣言されている場合、エンコーディング名はPythonによって認識される必要があります。 エンコーディングは、文字列リテラル、コメント、識別子を含むすべての字句解析に使用されます。


2.1.5。 明示的な線の結合

次のように、2つ以上の物理行を円記号(\)を使用して論理行に結合できます。物理行が文字列リテラルまたはコメントの一部ではない円記号で終わる場合、単一の論理行を形成した後、円記号とそれに続く行末文字を削除します。 例えば:

if 1900 < year < 2100 and 1 <= month <= 12 \
   and 1 <= day <= 31 and 0 <= hour < 24 \
   and 0 <= minute < 60 and 0 <= second < 60:   # Looks like a valid date
        return 1

バックスラッシュで終わる行にはコメントを付けることはできません。 バックスラッシュはコメントを継続しません。 バックスラッシュは、文字列リテラルを除いてトークンを継続しません(つまり、文字列リテラル以外のトークンは、バックスラッシュを使用して物理行に分割することはできません)。 文字列リテラルの外側の行の他の場所では、円記号は無効です。


2.1.6。 暗黙のライン結合

括弧、角括弧、または中括弧内の式は、円記号を使用せずに複数の物理行に分割できます。 例えば:

month_names = ['Januari', 'Februari', 'Maart',      # These are the
               'April',   'Mei',      'Juni',       # Dutch names
               'Juli',    'Augustus', 'September',  # for the months
               'Oktober', 'November', 'December']   # of the year

暗黙的に続く行にはコメントを含めることができます。 継続線のインデントは重要ではありません。 空白の継続行は許可されます。 暗黙の継続行の間にNEWLINEトークンはありません。 暗黙的に続く行は、トリプルクォートされた文字列内でも発生する可能性があります(以下を参照)。 その場合、コメントを載せることはできません。


2.1.7。 空白行

スペース、タブ、フォームフィード、および場合によってはコメントのみを含む論理行は無視されます(つまり、NEWLINEトークンは生成されません)。 ステートメントの対話型入力中、空白行の処理は、read-eval-printループの実装によって異なる場合があります。 標準の対話型インタプリタでは、完全に空白の論理行(つまり、 空白やコメントさえ含まないもの)は、複数行のステートメントを終了します。


2.1.8。 インデント

論理行の先頭にある先頭の空白(スペースとタブ)は、行のインデントレベルを計算するために使用され、次に、ステートメントのグループ化を決定するために使用されます。

タブは(左から右に)1から8のスペースに置き換えられ、置換を含む文字の総数は8の倍数になります(これはUnixで使用されるのと同じ規則であることが意図されています)。 次に、最初の空白以外の文字の前にあるスペースの総数によって、行のインデントが決まります。 インデントは、円記号を使用して複数の物理行に分割することはできません。 最初の円記号までの空白がインデントを決定します。

ソースファイルがスペース内のタブの価値に依存する意味になるようにタブとスペースを混在させている場合、インデントは矛盾しているとして拒否されます。 その場合、 TabError が発生します。

クロスプラットフォーム互換性に関する注意: UNIX以外のプラットフォームでのテキストエディタの性質上、単一のソースファイルのインデントにスペースとタブを組み合わせて使用することは賢明ではありません。 プラットフォームが異なると、最大インデントレベルが明示的に制限される場合があることにも注意してください。

行の先頭にフォームフィード文字が存在する場合があります。 上記のインデント計算では無視されます。 先頭の空白の他の場所にあるフォームフィード文字には、未定義の影響があります(たとえば、スペースカウントをゼロにリセットする場合があります)。

連続する行のインデントレベルは、次のように、スタックを使用してINDENTトークンとDEDENTトークンを生成するために使用されます。

ファイルの最初の行が読み取られる前に、単一のゼロがスタックにプッシュされます。 これは二度と飛び出すことはありません。 スタックにプッシュされる数は、常に下から上に厳密に増加します。 各論理行の先頭で、行のインデントレベルがスタックの最上位と比較されます。 それが等しい場合、何も起こりません。 大きい場合はスタックにプッシュされ、1つのインデントトークンが生成されます。 小さい場合は、スタックで発生する数値の1つである必要があります。 スタック上の大きい方のすべての番号がポップオフされ、ポップオフされた番号ごとにDEDENTトークンが生成されます。 ファイルの最後で、スタックに残っているゼロより大きい数値ごとにDEDENTトークンが生成されます。

正しく(紛らわしいが)インデントされたPythonコードの例を次に示します。

def perm(l):
        # Compute the list of all permutations of l
    if len(l) <= 1:
                  return [l]
    r = []
    for i in range(len(l)):
             s = l[:i] + l[i+1:]
             p = perm(s)
             for x in p:
              r.append(l[i:i+1] + x)
    return r

次の例は、さまざまなインデントエラーを示しています。

 def perm(l):                       # error: first line indented
for i in range(len(l)):             # error: not indented
    s = l[:i] + l[i+1:]
        p = perm(l[:i] + l[i+1:])   # error: unexpected indent
        for x in p:
                r.append(l[i:i+1] + x)
            return r                # error: inconsistent dedent

(実際には、最初の3つのエラーはパーサーによって検出されます。最後のエラーのみが字句解析プログラムによって検出されます。return rのインデントは、スタックからポップされたレベルと一致しません。)


2.1.9。 トークン間の空白

論理行の先頭または文字列リテラルを除いて、空白文字のスペース、タブ、およびフォームフィードは、トークンを区切るために交換可能に使用できます。 2つのトークンの間に空白が必要になるのは、それらの連結が別のトークンとして解釈される可能性がある場合のみです(たとえば、abは1つのトークンですが、abは2つのトークンです)。


2.2。 その他のトークン

NEWLINE、INDENT、DEDENTの他に、識別子キーワードリテラル演算子のトークンのカテゴリがあります。区切り文字。 空白文字(前述の行末記号以外)はトークンではありませんが、トークンを区切るのに役立ちます。 あいまいさが存在する場合、トークンは、左から右に読み取られたときに、正当なトークンを形成する可能な限り長い文字列で構成されます。


2.3。 識別子とキーワード

識別子(名前とも呼ばれます)は、次の字句定義によって記述されます。

Pythonの識別子の構文は、Unicode標準の付録UAX-31に基づいており、以下に定義されているように詳細と変更が加えられています。 詳細については、 PEP 3131 も参照してください。

ASCII範囲(U + 0001..U + 007F)内では、識別子の有効な文字はPython 2.xと同じです。大文字と小文字AからZ、アンダースコア_と、最初の文字を除いて、数字0から9

Python 3.0では、ASCII範囲外の追加の文字が導入されています( PEP 3131 を参照)。 これらの文字の分類では、 unicodedata モジュールに含まれているUnicode文字データベースのバージョンが使用されます。

識別子の長さは無制限です。 ケースは重要です。

 識別子   ::=  xid_start xid_continue*
  id_start     ::=  <all characters in general categories Lu, Ll, Lt, Lm, Lo, Nl, the underscore, and characters with the Other_ID_Start property>
  id_continue  ::=  <all characters in id_start, plus characters in the categories Mn, Mc, Nd, Pc and others with the Other_ID_Continue property>
  xid_start    ::=  <all characters in id_start whose NFKC normalization is in "id_start xid_continue*">
  xid_continue ::=  <all characters in id_continue whose NFKC normalization is in "id_continue*">

上記のUnicodeカテゴリコードは次の略です。

  • Lu -大文字
  • Ll -小文字
  • Lt -タイトルケース文字
  • Lm -修飾子文字
  • Lo -他の文字
  • Nl -文字番号
  • Mn -間隔のないマーク
  • Mc -マークを組み合わせる間隔
  • Nd -10進数
  • Pc -コネクタの句読点
  • Other_ID_Start -下位互換性をサポートするための PropList.txt 内の文字の明示的なリスト
  • Other_ID_Continue -同様に

すべての識別子は、解析中に通常の形式のNFKCに変換されます。 識別子の比較はNFKCに基づいています。

Unicode 4.1のすべての有効な識別子文字をリストした非規範的なHTMLファイルは、 https://www.unicode.org/Public/13.0.0/ucd/DerivedCoreProperties.txtにあります。

2.3.1。 キーワード

以下の識別子は、予約語または言語のキーワードとして使用されており、通常の識別子としては使用できません。 ここに書かれているとおりに正確に綴る必要があります。

False      await      else       import     pass
None       break      except     in         raise
True       class      finally    is         return
and        continue   for        lambda     try
as         def        from       nonlocal   while
assert     del        global     not        with
async      elif       if         or         yield

2.3.2。 識別子の予約済みクラス

特定のクラスの識別子(キーワード以外)には特別な意味があります。 これらのクラスは、先頭と末尾の下線文字のパターンによって識別されます。

_*

from module import *ではインポートされません。 特別な識別子_は、最後の評価の結果を格納するために対話型インタープリターで使用されます。 builtins モジュールに保存されます。 インタラクティブモードでない場合、_には特別な意味はなく、定義されていません。 セクションインポートステートメントを参照してください。

ノート

_という名前は、国際化と組み合わせて使用されることがよくあります。 この規則の詳細については、 gettext モジュールのドキュメントを参照してください。

__*__

非公式に「ダンダー」名として知られるシステム定義の名前。 これらの名前は、インタプリタとその実装(標準ライブラリを含む)によって定義されます。 現在のシステム名については、特別なメソッド名セクションなどで説明されています。 Pythonの将来のバージョンでは、さらに多くのことが定義される可能性があります。 __*__の使用は、明示的に文書化された使用に従わない場合、警告なしに破損する可能性があります。

__*

クラスプライベート名。 このカテゴリの名前は、クラス定義のコンテキスト内で使用される場合、基本クラスと派生クラスの「プライベート」属性間の名前の衝突を回避するために、マングル形式を使用するように書き直されます。 セクション識別子(名前)を参照してください。


2.4。 リテラル

リテラルは、一部の組み込み型の定数値の表記です。

2.4.1。 文字列とバイトのリテラル

文字列リテラルは、次の字句定義によって記述されます。

  stringliteral   ::=  [stringprefix](shortstring | longstring)
  stringprefix    ::=  "r" | "u" | "R" | "U" | "f" | "F"
                     | "fr" | "Fr" | "fR" | "FR" | "rf" | "rF" | "Rf" | "RF"
 ショートストリング     ::=  "'" shortstringitem* "'" | '"' shortstringitem* '"'
 ロングストリング      ::=  "'''" longstringitem* "'''" | '"""' longstringitem* '"""'
  shortstringitem ::=  shortstringchar | stringescapeseq
  longstringitem  ::=  longstringchar | stringescapeseq
  shortstringchar ::=  <any source character except "\" or newline or the quote>
  longstringchar  ::=  <any source character except "\">
  stringescapeseq ::=  "\" <any source character>
  bytesliteral   ::=  bytesprefix(shortbytes | longbytes)
  bytesprefix    ::=  "b" | "B" | "br" | "Br" | "bR" | "BR" | "rb" | "rB" | "Rb" | "RB"
 ショートバイト     ::=  "'" shortbytesitem* "'" | '"' shortbytesitem* '"'
  longbytes      ::=  "'''" longbytesitem* "'''" | '"""' longbytesitem* '"""'
  shortbytesitem ::=  shortbyteschar | bytesescapeseq
  longbytesitem  ::=  longbyteschar | bytesescapeseq
  shortbyteschar ::=  <any ASCII character except "\" or newline or the quote>
  longbyteschar  ::=  <any ASCII character except "\">
  bytesescapeseq ::=  "\" <any ASCII character>

これらのプロダクションで示されていない構文上の制限の1つは、stringprefixまたはbytesprefixとリテラルの残りの部分との間に空白が許可されないことです。 ソース文字セットは、エンコーディング宣言によって定義されます。 ソースファイルにエンコーディング宣言が指定されていない場合はUTF-8です。 セクションエンコーディング宣言を参照してください。

平易な英語:両方のタイプのリテラルは、一致する一重引用符(')または二重引用符(")で囲むことができます。 これらは、3つの一重引用符または二重引用符の一致するグループで囲むこともできます(これらは一般に三重引用符で囲まれた文字列と呼ばれます)。 バックスラッシュ(\)文字は、改行、バックスラッシュ自体、引用文字など、特別な意味を持つ文字をエスケープするために使用されます。

バイトリテラルには常に'b'または'B'のプレフィックスが付きます。 str タイプではなく、 bytes タイプのインスタンスを生成します。 ASCII文字のみを含めることができます。 128以上の数値を持つバイトは、エスケープで表現する必要があります。

文字列リテラルとバイトリテラルの両方に、オプションで文字'r'または'R'をプレフィックスとして付けることができます。 このような文字列は生の文字列と呼ばれ、円記号をリテラル文字として扱います。 その結果、文字列リテラルでは、生の文字列の'\U'および'\u'エスケープは特別に扱われません。 Python2.xの生のUnicodeリテラルがPython3.xとは異なる動作をすることを考えると、'ur'構文はサポートされていません。

バージョン3.3の新機能: rawバイトリテラルの'rb'プレフィックスが'br'の同義語として追加されました。


バージョン3.3の新機能:ユニコードレガシーリテラル(u'value')のサポートが再導入され、デュアルPython2.xおよび3.xコードベースのメンテナンスが簡素化されました。 詳細については、 PEP 414 を参照してください。


プレフィックスに'f'または'F'が含まれる文字列リテラルは、形式の文字列リテラルです。 フォーマットされた文字列リテラルを参照してください。 'f''r'と組み合わせることができますが、'b'または'u'と組み合わせることができないため、生のフォーマット済み文字列は可能ですが、フォーマット済みバイトリテラルはできません。

三重引用符で囲まれたリテラルでは、エスケープされていない改行と引用符が許可されます(保持されます)。ただし、行内の3つのエスケープされていない引用符はリテラルを終了します。 (「引用符」は、リテラルを開くために使用される文字です。 'または"のいずれか。)

'r'または'R'プレフィックスが存在しない限り、文字列およびバイトリテラルのエスケープシーケンスは、標準Cで使用されているものと同様のルールに従って解釈されます。 認識されるエスケープシーケンスは次のとおりです。

エスケープシーケンス 意味 メモ
\newline バックスラッシュと改行は無視されます
\\ バックスラッシュ(\
\' 一重引用符('
\" 二重引用符("
\a ASCIIベル(BEL)
\b ASCIIバックスペース(BS)
\f ASCIIフォームフィード(FF)
\n ASCIIラインフィード(LF)
\r ASCIIキャリッジリターン(CR)
\t ASCII水平タブ(TAB)
\v ASCII垂直タブ(VT)
\ooo 8進値の文字 ooo (1,3)
\xhh 16進値の文字 hh (2,3)

文字列リテラルでのみ認識されるエスケープシーケンスは次のとおりです。

エスケープシーケンス 意味 メモ
\N{name} Unicodeデータベースの name という名前の文字 (4)
\uxxxx 16ビットの16進値を持つ文字 xxxx (5)
\Uxxxxxxxx 32ビットの16進値を持つ文字 xxxxxxxx (6)

メモ

  1. 標準Cと同様に、最大3桁の8進数が受け入れられます。

  2. 標準Cとは異なり、正確に2桁の16進数が必要です。

  3. バイトリテラルでは、16進数と8進数のエスケープは、指定された値を持つバイトを示します。 文字列リテラルでは、これらのエスケープは、指定された値を持つUnicode文字を示します。

  4. バージョン3.3で変更:名前エイリアスのサポート 1 が追加されました。

  5. 正確に4桁の16進数が必要です。

  6. 任意のUnicode文字をこの方法でエンコードできます。 正確に8桁の16進数が必要です。

標準Cとは異なり、認識されないエスケープシーケンスはすべて文字列に変更されずに残されます。つまり、バックスラッシュは結果に残されます。 (この動作はデバッグ時に役立ちます。エスケープシーケンスの入力を間違えると、結果の出力が壊れていると認識されやすくなります。)文字列リテラルでのみ認識されるエスケープシーケンスは、バイトの認識されないエスケープのカテゴリに分類されることに注意することも重要です。リテラル。

バージョン3.6で変更:認識されないエスケープシーケンスは DeprecationWarning を生成します。 将来のPythonバージョンでは、 SyntaxWarning になり、最終的には SyntaxError になります。


生のリテラルでも、引用符は円記号でエスケープできますが、円記号は結果に残ります。 たとえば、r"\""は、円記号と二重引用符の2文字で構成される有効な文字列リテラルです。 r"\"は有効な文字列リテラルではありません(生の文字列でさえ、奇数の円記号で終了することはできません)。 具体的には、生のリテラルを単一の円記号で終了することはできません(円記号は次の引用文字をエスケープするため)。 また、単一の円記号とそれに続く改行は、リテラルの一部としての2つの文字として解釈され、行の継続としてはではなくとして解釈されることにも注意してください。


2.4.2。 文字列リテラルの連結

おそらく異なる引用規則を使用する、複数の隣接する文字列またはバイトリテラル(空白で区切られる)が許可され、それらの意味はそれらの連結と同じです。 したがって、"hello" 'world'"helloworld"と同等です。 この機能を使用すると、必要な円記号の数を減らしたり、長い文字列を長い行に便利に分割したり、文字列の一部にコメントを追加したりできます。たとえば、次のようになります。

re.compile("[A-Za-z_]"       # letter or underscore
           "[A-Za-z0-9_]*"   # letter, digit or underscore
          )

この機能は構文レベルで定義されていますが、コンパイル時に実装されることに注意してください。 実行時に文字列式を連結するには、「+」演算子を使用する必要があります。 また、リテラル連結では、コンポーネントごとに異なる引用スタイルを使用でき(生の文字列と三重引用文字列を混合する場合でも)、フォーマットされた文字列リテラルをプレーン文字列リテラルと連結できることにも注意してください。


2.4.3。 フォーマットされた文字列リテラル

バージョン3.6の新機能。


形式の文字列リテラルまたは f-string は、接頭辞'f'または'F'が付いた文字列リテラルです。 これらの文字列には、中括弧{}で区切られた式である置換フィールドが含まれる場合があります。 他の文字列リテラルは常に定数値を持ちますが、フォーマットされた文字列は実際には実行時に評価される式です。

エスケープシーケンスは、通常の文字列リテラルと同様にデコードされます(リテラルが生の文字列としてもマークされている場合を除く)。 デコード後、文字列の内容の文法は次のようになります。

  f_string          ::=  (literal_char | "{{" | "}}" | replacement_field)*
  replacement_field ::=  "{" f_expression ["="] ["!" conversion] [":" format_spec] "}"
  f_expression      ::=  (conditional_expression | "*" or_expr)
                         ("," conditional_expression | "," "*" or_expr)* [","]
                       | yield_expression
 変換        ::=  "s" | "r" | "a"
  format_spec       ::=  (literal_char | NULL | replacement_field)*
  literal_char      ::=  <any code point except "{", "}" or NULL>

中括弧の外側の文字列の部分は文字通りに扱われますが、二重中括弧'{{'または'}}'は対応する単一中括弧に置き換えられます。 単一の開き中括弧'{'は、Python式で始まる置換フィールドをマークします。 評価後に式のテキストとその値の両方を表示するために(デバッグに役立ちます)、式の後に等号'='を追加できます。 感嘆符'!'によって導入された変換フィールドが続く場合があります。 コロン':'で導入されたフォーマット指定子を追加することもできます。 置換フィールドは、閉じ中括弧'}'で終わります。

フォーマットされた文字列リテラルの式は、いくつかの例外を除いて、括弧で囲まれた通常のPython式のように扱われます。 空の式は使用できません。ラムダと代入式:=の両方を明示的な括弧で囲む必要があります。 置換式には改行を含めることができます(例: 三重引用符で囲まれた文字列)。ただし、コメントを含めることはできません。 各式は、フォーマットされた文字列リテラルが表示されるコンテキストで、左から右の順に評価されます。

バージョン3.7で変更: Python 3.7より前は、 await 式と、 async for 句を含む内包表記は、フォーマットされた文字列リテラルの式では、実装に問題があります。


等号'='が指定されている場合、出力には式テキスト、'='、および評価値が含まれます。 開始中括弧'{'の後、式内、および'='の後のスペースは、すべて出力に保持されます。 デフォルトでは、'='により、形式が指定されていない限り、式の repr()が提供されます。 形式を指定すると、変換'!r'が宣言されていない限り、デフォルトで式の str()になります。

バージョン3.8の新機能:等号'='


変換が指定されている場合、式の評価結果はフォーマット前に変換されます。 変換'!s'は結果に対して str()を呼び出し、'!r'repr()を呼び出し、'!a'asciiを呼び出します()

次に、結果は format()プロトコルを使用してフォーマットされます。 形式指定子は、式または変換結果の__format__()メソッドに渡されます。 フォーマット指定子を省略すると、空の文字列が渡されます。 フォーマットされた結果は、文字列全体の最終値に含まれます。

トップレベルのフォーマット指定子には、ネストされた置換フィールドが含まれる場合があります。 これらのネストされたフィールドには、独自の変換フィールドと形式指定子が含まれる場合がありますが、より深くネストされた置換フィールドが含まれない場合があります。 フォーマット指定子ミニ言語は、 str.format()メソッドで使用されるものと同じです。

フォーマットされた文字列リテラルは連結できますが、置換フィールドをリテラル間で分割することはできません。

フォーマットされた文字列リテラルのいくつかの例:

>>> name = "Fred"
>>> f"He said his name is {name!r}."
"He said his name is 'Fred'."
>>> f"He said his name is {repr(name)}."  # repr() is equivalent to !r
"He said his name is 'Fred'."
>>> width = 10
>>> precision = 4
>>> value = decimal.Decimal("12.34567")
>>> f"result: {value:{width}.{precision}}"  # nested fields
'result:      12.35'
>>> today = datetime(year=2017, month=1, day=27)
>>> f"{today:%B %d, %Y}"  # using date format specifier
'January 27, 2017'
>>> f"{today=:%B %d, %Y}" # using date format specifier and debugging
'today=January 27, 2017'
>>> number = 1024
>>> f"{number:#0x}"  # using integer format specifier
'0x400'
>>> foo = "bar"
>>> f"{ foo = }" # preserves whitespace
" foo = 'bar'"
>>> line = "The mill's closed"
>>> f"{line = }"
'line = "The mill\'s closed"'
>>> f"{line = :20}"
"line = The mill's closed   "
>>> f"{line = !r:20}"
'line = "The mill\'s closed" '

通常の文字列リテラルと同じ構文を共有することの結果は、置換フィールドの文字が、外側のフォーマットされた文字列リテラルで使用される引用符と競合してはならないということです。

f"abc {a["x"]} def"    # error: outer string literal ended prematurely
f"abc {a['x']} def"    # workaround: use different quoting

フォーマット式では円記号は使用できず、エラーが発生します。

f"newline: {ord('\n')}"  # raises SyntaxError

バックスラッシュエスケープが必要な値を含めるには、一時変数を作成します。

>>> newline = ord('\n')
>>> f"newline: {newline}"
'newline: 10'

書式設定された文字列リテラルは、式が含まれていない場合でも、docstringとして使用することはできません。

>>> def foo():
...     f"Not a docstring"
...
>>> foo.__doc__ is None
True

フォーマットされた文字列リテラルを追加した提案については、 PEP 498 、および関連するフォーマット文字列メカニズムを使用する str.format()も参照してください。


2.4.4。 数値リテラル

数値リテラルには、整数、浮動小数点数、虚数の3種類があります。 複素数リテラルはありません(複素数は、実数と虚数を加算することで形成できます)。

数値リテラルには符号が含まれていないことに注意してください。 -1のような句は、実際には単項演算子 '-'とリテラル1で構成される式です。


2.4.5。 整数リテラル

整数リテラルは、次の字句定義によって記述されます。

 整数      ::=  decinteger | bininteger | octinteger | hexinteger
  decinteger   ::=  nonzerodigit (["_"] digit)* | "0"+ (["_"] "0")*
  bininteger   ::=  "0" ("b" | "B") (["_"] bindigit)+
  octinteger   ::=  "0" ("o" | "O") (["_"] octdigit)+
  hexinteger   ::=  "0" ("x" | "X") (["_"] hexdigit)+
 ゼロ桁以外 ::=  "1"..."9"
 桁        ::=  "0"..."9"
  bindigit     ::=  "0" | "1"
  octdigit     ::=  "0"..."7"
  16桁     ::=  digit | "a"..."f" | "A"..."F"

使用可能なメモリに格納できるものを除いて、整数リテラルの長さに制限はありません。

リテラルの数値を決定するために、アンダースコアは無視されます。 読みやすさを向上させるために数字をグループ化するために使用できます。 1つのアンダースコアは、数字の間、および0xなどの基本指定子の後に発生する可能性があります。

ゼロ以外の10進数の先行ゼロは許可されないことに注意してください。 これは、Pythonがバージョン3.0より前に使用していたCスタイルの8進リテラルを使用して曖昧さを解消するためのものです。

整数リテラルのいくつかの例:

7     2147483647                        0o177    0b100110111
3     79228162514264337593543950336     0o377    0xdeadbeef
      100_000_000_000                   0b_1110_0101

バージョン3.6での変更:リテラルでのグループ化の目的でアンダースコアが許可されるようになりました。


2.4.6。 浮動小数点リテラル

浮動小数点リテラルは、次の字句定義によって記述されます。

  floatnumber   ::=  pointfloat | exponentfloat
  pointfloat    ::=  [digitpart] fraction | digitpart "."
  exponentfloat ::=  (digitpart | pointfloat) exponent
  Digitpart     ::=  digit (["_"] digit)*
 分数      ::=  "." digitpart
 指数      ::=  ("e" | "E") ["+" | "-"] digitpart

整数部分と指数部分は常に基数10を使用して解釈されることに注意してください。 たとえば、077e010は有効であり、77e10と同じ番号を示します。 浮動小数点リテラルの許容範囲は、実装によって異なります。 整数リテラルと同様に、数字のグループ化にはアンダースコアがサポートされています。

浮動小数点リテラルのいくつかの例:

3.14    10.    .001    1e100    3.14e-10    0e0    3.14_15_93

バージョン3.6での変更:リテラルでのグループ化の目的でアンダースコアが許可されるようになりました。


2.4.7。 架空のリテラル

架空のリテラルは、次の字句定義によって記述されます。

  imagnumber ::=  (floatnumber | digitpart) ("j" | "J")

虚数リテラルは、実数部が0.0の複素数を生成します。 複素数は浮動小数点数のペアとして表され、その範囲には同じ制限があります。 実数がゼロ以外の複素数を作成するには、(3+4j)のように浮動小数点数を追加します。 虚数リテラルのいくつかの例:

3.14j   10.j    10j     .001j   1e100j   3.14e-10j   3.14_15_93j

2.5。 演算子

次のトークンは演算子です。

+       -       *       **      /       //      %      @
<<      >>      &       |       ^       ~       :=
<       >       <=      >=      ==      !=

2.6。 区切り文字

次のトークンは、文法の区切り文字として機能します。

(       )       [       ]       {       }
,       :       .       ;       @       =       ->
+=      -=      *=      /=      //=     %=      @=
&=      |=      ^=      >>=     <<=     **=

ピリオドは、浮動小数点リテラルおよび虚数リテラルでも発生する可能性があります。 3つのピリオドのシーケンスには、省略記号リテラルとして特別な意味があります。 リストの後半である拡張代入演算子は、字句的に区切り文字として機能しますが、操作も実行します。

次の印刷ASCII文字は、他のトークンの一部として特別な意味を持っているか、字句解析プログラムにとって重要です。

'       "       #       \

次の印刷ASCII文字はPythonでは使用されません。 文字列リテラルとコメントの外部でのそれらの発生は、無条件のエラーです。

$       ?       `

脚注

1
https://www.unicode.org/Public/11.0.0/ucd/NameAliases.txt