1. はじめに

このリファレンスマニュアルは、Python プログラミング言語自体に関する記述です。チュートリアルとして書かれたものではありません。

私は本マニュアルをできるだけ正確に書こうとする一方で、文法や字句解析以外の全てについて、形式化された仕様記述ではなく英語を使うことにしました。そうすることで、このドキュメントが平均的な読者にとってより読みやすくなっているはずですが、ややあいまいな部分も残っていることでしょう。従って、もし読者のあなたが火星から来ている人で、このドキュメントだけから Python を再度実装しようとしているのなら、色々と推測しなければならないことがあり、実際にはおそらく全く別の言語を実装する羽目になるでしょう。逆に、あなたが Python を利用しており、Python 言語のある特定の領域において、厳密な規則が何か疑問に思った場合、その答えはこのドキュメントで確実に見つけられることでしょう。もしより形式化された言語定義をお望みなら、あなたの時間を提供していただいてかまいません --- もしくは、クローン生成装置でも発明してください :-)。

実装に関する詳細を言語リファレンスのドキュメントに載せすぎるのは危険なことです --- 実装は変更されるかもしれず、同じ言語でも異なる実装は異なった動作をするかもしれないからです。一方、CPython が広く使われている一つの Python 実装 (別の実装も支持され続けていますが) なので、特定のクセについては、特に実装によって何らかの制限が加えられている場合には、触れておく価値があります。従って、このテキスト全体にわたって短い "実装に関する注釈 (imprementation notes)" がちりばめられています。

Python 実装はいずれも、数々の組み込みモジュールと標準モジュールが付属します。それらについては、 Python 標準ライブラリ でドキュメント化されています。いくつかの組み込みモジュールについては、言語定義と重要なかかわりをもっているときについて触れています。

1.1. 別のPythonの実装

Pythonの実装としては、群を抜いて有名な実装がひとつ存在しています。それ以外の実装に関しても、特定のユーザ間で興味が持たれています。

よく知られている実装には以下のものがあります:

CPython

これは最も保守されている初代のPython実装で、C言語で書かれています。ほとんどの場合、言語の新機能がいち早く実装されます。

Jython

Javaで実装されたPythonです。この実装はJavaアプリケーションのためのスクリプト言語として、もしくはJavaクラスライブラリを使ったアプリケーションを作成するために使用することができます。また、Javaライブラリのテストを作成するためにもしばしば使用されています。さらなる情報については the Jython website を参照してください。

Python for .NET

この実装は内部では CPython を使いますが、それ自体がマネージド .NET アプリケーションであり、.NET ライブラリを利用できます。 Brian Lloyd が作成しました。 詳しくは Python for .NET home page を参照してください。

IronPython

.NET 向けのもう一つの Python 実装です。 Python.NET とは異なり、IL を生成して Python コードを直接 .NET アセンブリにコンパイルする、完全な Python 実装です。 Jython の最初の開発者である Jim Hugunin が作成しました。 詳しくは the IronPython website を参照してください。

PyPy

完全にPythonで書かれたPythonの実装です。他の実装には見られない、スタックレスのサポートや、実行時 (Just in Time) コンパイラなどの高度な機能をサポートしています。このプロジェクトの一つの目的は、(Pythonで書かれていることによって、)インタプリタを簡単に修正できるようにして、言語自体での実験を後押しすることです。さらなる情報は the PyPy project's home page にあります。

これらの実装はそれぞれ、このマニュアルに記載された言語と何らかの違いがあるか、Python の標準ドキュメントの範囲を超える固有の情報があります。 使用する実装についてほかに知っておくべきことは、その実装固有のドキュメントを参照してください。

1.2. 本マニュアルにおける表記法

字句解析と構文の説明には、EBNF と PEG を組み合わせた文法の記法を使います。 例えば次のようになります。

name:   letter (letter | digit | "_")*
letter: "a"..."z" | "A"..."Z"
digit:  "0"..."9"

この例の最初の行は、name が letter で始まり、その後に letter、digit、アンダースコアが 0 個以上続くことを示しています。 letter は 'a' から 'z'、または A から Z までのいずれか 1 文字で、digit は 0 から 9 までのいずれか 1 文字です。

各規則は、定義する規則を識別する名前で始まり、その後にコロン : が続きます。 コロンの右側の定義には、次の構文要素を使います。

  • name: 名前は別の規則を参照します。 可能な場合は、その規則の定義へのリンクになっています。

    • TOKEN: 大文字の名前は トークン を参照します。 文法の定義では、トークンは規則と同じように扱います。

  • "text"、'text': シングルクォートまたはダブルクォートで囲まれたテキストは、引用符を除いた内容に文字どおり一致する必要があります。 引用符の種類は text の意味に応じて選びます。

    • 'if': シングルクォートで囲まれた名前は キーワード を表します。

    • "case": ダブルクォートで囲まれた名前は ソフトキーワード を表します。

    • '@': シングルクォートで囲まれた、英字以外の記号は OP トークンを表します。 これは 区切り文字 または 演算子 です。

  • e1 e2: 空白だけで区切った項目は、並びを表します。 この場合、e1 の後に e2 が続く必要があります。

  • e1 | e2: 縦棒は選択肢を区切ります。 PEG の「順序付き選択」を表し、e1 が一致すれば e2 は検討しません。 従来の PEG 文法では、縦棒ではなくスラッシュ / で記述します。 背景や詳細は PEP 617 を参照してください。

  • e*: アスタリスクは、直前の項目の 0 回以上の繰り返しを表します。

  • e+: 同様に、プラス記号は 1 回以上の繰り返しを表します。

  • [e]: 角括弧で囲まれた部分は、0 回または 1 回の出現を表します。 つまり、囲まれた部分は省略可能です。

  • e?: 疑問符は角括弧とまったく同じ意味で、直前の項目が省略可能であることを表します。

  • (e): 丸括弧はグループ化に使います。

次の記法は 字句定義 でのみ使います。

  • "a"..."z": 三つのドットで区切った二つのリテラル文字は、指定された ASCII 文字の範囲 (両端を含む) にある任意の 1 文字の選択を表します。

  • <...>: 山括弧で囲まれた部分には、一致する記号の非形式的な説明 (例: <any ASCII character except "\">) または近くの本文で定義した略記 (例: <Lu>) を記述します。

一部の定義では 先読み も使います。 これは入力を消費せずに、指定された位置で要素が一致しなければならないこと、または一致してはならないことを示します。

  • &e: 肯定先読み (e が一致する必要があります)

  • !e: 否定先読み (e が一致しては なりません)

単項演算子 (*、+、?) は可能な限り強く結合し、縦棒 (|) は最も弱く結合します。

空白はトークンを区切るためだけに意味を持ちます。

通常、規則は 1 行に記述しますが、長すぎる規則は折り返せます。

literal: stringliteral | bytesliteral
         | integer | floatnumber | imagnumber

別の形式として、最初の行をコロンで終え、各選択肢を新しい行の縦棒で始めることもできます。 例えば次のようになります。

literal:
   | stringliteral
   | bytesliteral
   | integer
   | floatnumber
   | imagnumber

これは、最初の選択肢が空であるという意味では ありません。

1.2.1. 字句定義と構文定義

字句 解析と 構文 解析には違いがあります。 字句解析器 は入力ソースの個々の文字を処理し、パーサ (構文解析器) は字句解析で生成された トークン の列を処理します。 ただし、二つの段階の正確な境界が CPython の実装の詳細に属する場合もあります。

両者の実際上の違いは、字句 定義ではすべての空白に意味があることです。 字句解析器は、token.INDENT や NEWLINE などのトークンに変換されない空白をすべて 破棄します。 その後の 構文 定義は、ソースの文字ではなく、これらのトークンを使います。

このドキュメントでは、どちらの形式の定義にも同じ BNF 文法を使います。 次の章 (字句解析) で使う BNF はすべて字句定義で、それ以降の章で使うものは構文定義です。