5. 式 (expression)

この章では、Python の式における個々の要素の意味について解説します。

表記法に関する注意: この章と以降の章での拡張BNF (extended BNF) 表記は、字句解析規則ではなく、構文規則を記述するために用いられています。ある構文規則 (のある表現方法) が、以下の形式

name ::=  othername

で記述されていて、この構文特有の意味付け (semantics) が記述されていない場合、 name の形式をとる構文の意味付けは othername の意味付けと同じになります。

5.1. 算術変換 (arithmetic conversion)

以下の算術演算子の記述で、「数値引数は共通の型に変換されます」と書かれている場合、引数は 型強制規則 (coercion rule) に記載されている型強制規則に基づいて型強制されます。引数がいずれも標準の数値型である場合、以下の型強制が適用されます:

  • 片方の引数が複素数型であれば、他方は複素数型に変換されます;
  • それ以外の場合で、片方の引数が浮動小数点数であれば、他方は浮動小数点型に変換されます;
  • それ以外の場合で、片方の引数が長整数型であれば、他方は長整数型に変換されます;
  • それ以外の場合で、両方の引数が通常の整数型であれば、変換の必要はありません。

特定の演算子 (文字列を左引数とする '%' 演算子など) では、さらに別の規則が適用されます。拡張をおこなうことで、個々の演算子に対する型強制を定義できます。

5.2. アトム、原子的要素 (atom)

アトム (原子的要素: atom) は、式を構成する基本単位です。もっとも単純なアトムは、識別子またはリテラルになります。逆クオートや丸括弧、波括弧、または角括弧で囲われた形式 (form) もまた、文法的にはアトムに分類されます。アトムの構文定義は以下のようになります:

atom      ::=  identifier | literal | enclosure
enclosure ::=  parenth_form | list_display
               | generator_expression | dict_display | set_display
               | string_conversion | yield_atom

5.2.1. 識別子 (identifier、または名前 (name))

アトムの形になっている識別子 (identifier) は名前 (name) です。字句定義については 識別子 (identifier) およびキーワード (keyword) 節を、名前付けや束縛については 名前づけと束縛 (naming and binding) 節を参照してください。

名前があるオブジェクトに束縛されている場合、名前 atom を評価するとそのオブジェクトになります。名前が束縛されていない場合、 atom を評価しようとすると NameError 例外を送出します。

プライベートな名前の名前修飾: クラス定義内に書かれた識別子で、2つ以上のアンダースコアから始まり、末尾が2つ以上のアンダースコアで終わっていないものは、そのクラスの プライベートな名前 とみなされます。プライベートな名前は、コードが生成される前により長い形式に変換されます。この変換によって、クラス名の先頭にアンダースコアがあれば除去し、先頭にアンダースコアを1つ付加し、名前の前に挿入されます。例えば、クラス名 Ham の中の識別子 __spam は、_Ham__spam に変換されます。変換は識別子が使用されている構文のコンテキストからは独立しています。変換された名前が非常に長い (255文字を超える) 場合、実装によっては名前の切り詰めが行われるかもしれません。クラス名がアンダースコアのみから成る場合は変換は行われません。

5.2.2. リテラル

Python では、文字列リテラルと、様々な数値リテラルをサポートしています:

literal ::=  stringliteral | integer | longinteger
             | floatnumber | imagnumber

リテラルを評価すると、指定した型 (文字列、整数、長整数、浮動小数点数、複素数) の指定した値を持つオブジェクトになります。浮動小数点や虚数 (複素数) リテラルの場合、値は近似値になる場合があります。詳しくは リテラル を参照してください。

リテラルは全て変更不能なデータ型に対応します。このため、オブジェクトのアイデンティティはオブジェクトの値ほど重要ではありません。同じ値を持つ複数のリテラルを評価した場合、(それらのリテラルがプログラムの同じ場所由来のものであっても、そうでなくても) 同じオブジェクトを指しているか、まったく同じ値を持つ別のオブジェクトになります。

5.2.3. 丸括弧形式 (parenthesized form)

丸括弧形式とは、式リストの一形態で、丸括弧で囲ったものです:

parenth_form ::=  "(" [expression_list] ")"

丸括弧で囲われた式のリストは、個々の式が表現するものになります: リスト内に少なくとも一つのカンマが入っていた場合、タプルになります; そうでない場合、式のリストを構成している単一の式自体の値になります。

中身が空の丸括弧のペアは、空のタプルオブジェクトを表します。タプルは変更不能なので、リテラルと同じ規則が適用されます (すなわち、空のタプルが二箇所で使われると、それらは同じオブジェクトになることもあるし、ならないこともあります)。

タプルは丸括弧で作成されるのではなく、カンマによって作成されることに注意してください。例外は空のタプルで、この場合には丸括弧が 必要です — 丸括弧のつかない "何も記述しない式 (nothing)" を使えるようにしてしまうと、文法があいまいなものになってしまい、よくあるタイプミスが検出されなくなってしまいます。

5.2.4. リスト表現

リスト表現は、角括弧で囲われた式の系列です。系列は空の系列であってもかまいません:

list_display        ::=  "[" [expression_list | list_comprehension] "]"
list_comprehension  ::=  expression list_for
list_for            ::=  "for" target_list "in" old_expression_list [list_iter]
old_expression_list ::=  old_expression [("," old_expression)+ [","]]
old_expression      ::=  or_test | old_lambda_expr
list_iter           ::=  list_for | list_if
list_if             ::=  "if" old_expression [list_iter]

リスト表現は、新に作成されたリストオブジェクトを表します。新たなリストの内容は、式のリストを与えるか、リストの内包表記 (list comprehension) で指定します。カンマで区切られた式のリストを与えた場合、リストの各要素は左から右へと順に評価され、評価された順番にリスト内に配置されます。リストの内包表記を与える場合、内包表記はまず単一の式、続いて少なくとも一つの for 節、続いてゼロ個以上の for 節か if 節になります。この場合、新たに作成されるリストの各要素は、各々の forif 節を左から右の順にネストしたブロックとみなして実行し、ネストの最内ブロックに到達する度に式を評価した値となります。 [1]

5.2.5. 集合と辞書の表現

Python は、集合や辞書を構成するために、"表現 (display)" と呼ばれる特殊な構文を、それぞれ二種類づつ提供していて、コンテナの内容は:

  • 明示的に列挙される、または
  • 内包表記 (comprehension) と呼ばれる、ループ処理とフィルター処理の命令の組み合わせを通じて計算されます。

内包表記の共通の構文要素はこの通りです:

comprehension ::=  expression comp_for
comp_for      ::=  "for" target_list "in" or_test [comp_iter]
comp_iter     ::=  comp_for | comp_if
comp_if       ::=  "if" expression_nocond [comp_iter]

内包表記はまず単一の式、続いて for 節、さらに続いて 0 個以上の for 節や if 節からなります。この場合、新たなコンテナの各要素は、各々の forif 節を、左から右にネストしたブロックとみなして実行し、ネストの最内のブロックに到達する度に式を評価することで作成されたものになります。

なお、これらの内包表記は別のスコープで実行されるので、対象のリスト内で代入された名前が外側のスコープに "漏れる" ことはありません。

5.2.6. ジェネレータ式

ジェネレータ式 (generator expression) とは、丸括弧を使ったコンパクトなジェネレータ表記法です:

generator_expression ::=  "(" expression comp_for ")"

ジェネレータ式は新たなジェネレータオブジェクトを与えます。この構文は内包表記とほぼ同じですが、角括弧や波括弧ではなく、丸括弧で囲まれます。

ジェネレータ式で使われる変数は、ジェネレータオブジェクトに next() メソッドが呼び出されたときに遅延評価されます (通常のジェネレータと同じ流儀です)。しかし、最も左に位置する for 節は直ちに評価されるため、そこで生じたエラーは、ジェネレータ式を扱うコードで起こりえる他のエラーの前に現れることがあります。その後に続く for 節は、その前の for ループに依存しているため、直ちには評価されません。例: (x*y for x in range(10) for y in bar(x))

関数の唯一の引数として渡す場合には、丸括弧を省略できます。詳しくは 呼び出し (call) 節を参照してください。

5.2.7. 辞書表現

辞書表現は、波括弧で囲われた、キーと値のペアからなる系列です。系列は空の系列であってもかまいません:

dict_display       ::=  "{" [key_datum_list | dict_comprehension] "}"
key_datum_list     ::=  key_datum ("," key_datum)* [","]
key_datum          ::=  expression ":" expression
dict_comprehension ::=  expression ":" expression comp_for

辞書表現は、新たな辞書オブジェクトを表します。

カンマ区切りの一連のキー/データの対が与えられたときは、その要素は左から右へ評価され、辞書の項目を定義します。すなわち、それぞれのキーオブジェクトが、辞書内で対応するデータを保存するキーとして使われます。これにより、キー/データリストの中で同じキーを複数回指定することができ、そのキーに対する最終的な辞書の値は、最後に与えられたものになります。

辞書内包表記は、リストや集合の内包表記とは対照的に、通常の "for" や "if" 節の前に、コロンで分けられた 2 つの式が必要です。内包表記が起動すると、結果のキーと値の要素が、作られた順に新しい辞書に挿入されます。

キーの値として使える型に関する制限は 標準型の階層 節ですでに列挙しています。(一言でいうと、キーは変更可能なオブジェクトを全て排除した hashable でなければなりません。) 重複するキー間で衝突が起きても、衝突が検出されることはありません; あるキーに対して、最後に渡されたデータ (プログラムテキスト上では、辞書表記の最も右側値となるもの) が使われます。

5.2.8. 集合表現

集合表現は波括弧で表され、キーと値を分けるコロンがないことで辞書表現と区別されます:

set_display ::=  "{" (expression_list | comprehension) "}"

集合表示は、一連の式または内包表記によって指定された内容の、ミュータブルな集合オブジェクトを与えます。カンマ区切りの一連の式が与えられたときは、その要素は左から右へ順に評価され、集合オブジェクトに加えられます。内包表記が与えられたときは、内包表記の結果となる要素で集合が構成されます。

空集合は {} で構成できません。このリテラルは空の辞書を構成します。

5.2.9. 文字列変換

文字列変換は、逆クオート (reverse quite, 別名バッククオート: backward quote) で囲われた式のリストです:

string_conversion ::=  "`" expression_list "`"

文字列変換は、逆クオート内の式リストを評価して、評価結果のオブジェクトを各オブジェクトの型特有の規則に従って文字列に変換します。

オブジェクトが文字列、数値、 None か、それらの型のオブジェクトのみを含むタプル、リストまたは辞書の場合、評価結果の文字列は有効な Python 式となり、組み込み関数 eval() に渡した場合に同じ値となります (浮動小数点が含まれている場合には近似値の場合もあります)。

(特に、文字列を変換すると、値を安全に出力するために文字列の両側にクオートが付けられ、"変 (funny) な" 文字はエスケープシーケンスに変換されます。)

再帰的な構造をもつオブジェクト (例えば自分自身を直接または間接的に含むリストや辞書) では ... を使って再帰的参照であることが示され、オブジェクトの評価結果は eval() に渡しても等価な値を得ることができません (SyntaxError が送出されます)。

組み込み関数 repr() は、括弧内の引数に対して、逆クオート表記で囲われた中身と全く同じ変換を実行します。組み込み関数 str() は似たような動作をしますが、もっとユーザフレンドリな変換になります。

5.2.10. Yield 式

yield_atom       ::=  "(" yield_expression ")"
yield_expression ::=  "yield" [expression_list]

バージョン 2.5 で追加.

yield 式はジェネレータ関数を定義するときにその関数の内部でのみ使用されます。関数内で yield 式を使用すると、普通の関数ではなくジェネレータ関数が作成されます。

ジェネレータ関数が呼び出されるとき、ジェネレータとしてのイテレータを返します。そのジェネレータはジェネレータ関数の実行を制御します。ジェネレータのメソッドが呼び出されるときに実行が開始されます。メソッドを呼び出すと、実行は yield の最初の位置まで処理されて一時停止します。そして、ジェネレータの呼び出し元へ expression_list の値を返します。ここで言う一時停止とは、ローカル変数の束縛、命令ポインタや内部の評価スタックを含めたローカルの全ての状態が保持されることを指します。再度、ジェネレータのメソッドを呼び出して実行を再開するとき、そのジェネレータ関数はまさに yield 式がただの外部呼び出しであったかのように処理が継続されます。再開した後の yield 式の値は実行を再開するメソッドに依存します。

これまで説明した内容から、ジェネレータ関数はコルーチンにとてもよく似ています。ジェネレータ関数は何度も生成し、1つ以上のエントリポイントを持ち、その実行は一時停止されます。ジェネレータ関数は yield した後で実行の継続を制御できないことが唯一の違いです。その制御は常にジェネレータの呼び出し元へ移されます。

5.2.10.1. ジェネレータ-イテレータメソッド

この説ではジェネレータイテレータのメソッドについて説明します。これらはジェネレータ関数の実行制御に使用できます。

以下のジェネレータメソッドの呼び出しは、ジェネレータが既に実行中の場合 ValueError 例外を送出する点に注意してください。

generator.next()

ジェネレータ関数の実行を開始するか、最後に yield 式が実行されたところから再開します。ジェネレータ関数が next() メソッドによって再開された時、その時点の yield 式の値は常に None と評価されます。その後次の yield 式まで実行し、ジェネレータは一時停止し、 expression_list の値を next() メソッドの呼び出し元に返します。ジェネレータが次の値を yield せずに終了した場合、 StopIteration 例外が送出されます。

generator.send(value)

ジェネレータ関数の内部へ値を "送り"、実行を再開します。引数の value はカレントの yield 式の結果になります。 send() メソッドはジェネレータが生成した次の値、またはジェネレータが値を生成することなく終了すると StopIteration が発生します。ジェネレータが再開するために send() を呼び出すときは、引数として None を指定しなければなりません。そうしないと、値を受け取る yield 式が存在しないからです。

generator.throw(type[, value[, traceback]])

ジェネレータが中断した位置で type 型の例外を発生させて、ジェネレータ関数が生成する次の値を返します。ジェネレータが値を生成することなく終了すると StopIteration が発生します。ジェネレータ関数が渡された例外を捕捉しない、もしくは違う例外を発生させるなら、その例外は呼び出し元へ伝搬されます。

generator.close()

ジェネレータ関数が中断した位置で GeneratorExit を発生させます。ジェネレータ関数が (通常の終了または既にクローズされたことで) StopIteration 、もしくは (例外を捕捉しないことで) GeneratorExit を発生させる場合 close() は呼び出し元へ返されます。ジェネレータが値を生成する場合 RuntimeError が発生します。 close() はジェネレータが通常の終了または例外により既に終了している場合は何もしません。

以下の簡単なサンプルはジェネレータとジェネレータ関数の振る舞いを実際に紹介します:

>>> def echo(value=None):
...     print "Execution starts when 'next()' is called for the first time."
...     try:
...         while True:
...             try:
...                 value = (yield value)
...             except Exception, e:
...                 value = e
...     finally:
...         print "Don't forget to clean up when 'close()' is called."
...
>>> generator = echo(1)
>>> print generator.next()
Execution starts when 'next()' is called for the first time.
1
>>> print generator.next()
None
>>> print generator.send(2)
2
>>> generator.throw(TypeError, "spam")
TypeError('spam',)
>>> generator.close()
Don't forget to clean up when 'close()' is called.

参考

PEP 0342 - 拡張されたジェネレータを用いたコルーチン
シンプルなコルーチンとして利用できるように、ジェネレータの構文と API を拡張する提案です。

5.3. プライマリ

プライマリは、言語において最も結合の強い操作を表します。文法は以下のようになります:

primary ::=  atom | attributeref | subscription | slicing | call

5.3.1. 属性参照

属性参照は、プライマリの後ろにピリオドと名前を連ねたものです:

attributeref ::=  primary "." identifier

プライマリの値評価結果は、例えばモジュール、リスト、インスタンスといった、属性参照をサポートする型でなければなりません。オブジェクトは次に、指定した名前が識別子名となっているような属性を生成するよう問い合わせされます。問い合わせた属性が得られない場合、例外 AttributeError が送出されます。それ以外の場合、オブジェクトは属性オブジェクトの型と値を決定し、生成して返します。同じ属性参照を複数回評価したとき、互いに異なる属性オブジェクトになることがあります。

5.3.2. 添字表記 (subscription)

添字表記は、シーケンス (文字列、タプルまたはリスト) やマップ (辞書) オブジェクトから、要素を一つ選択します:

subscription ::=  primary "[" expression_list "]"

プライマリの値評価結果は、シーケンス型かマップ型のオブジェクトでなければなりません。

プライマリがマップであれば、式リストの値評価結果はマップ内のいずれかのキー値に相当するオブジェクトにならなければなりません。添字表記は、そのキーに対応するマップ内の値 (value) を選択します。 (式リストの要素が単独である場合を除き、式リストはタプルでなければなりません。)

プライマリがシーケンスの場合、式 (リスト) の値評価結果は (通常の) 整数でなければなりません。値が負の場合、シーケンスの長さが加算されます (x[-1]x の最後の要素を指すことになります)。加算結果はシーケンス内の要素数よりも小さな非負の整数とならなければなりません。添字表記は、添字と同じシーケンス中の (ゼロから数えた) インデクスを持つ要素を選択します。

文字列型の要素は文字 (character) です。文字は個別の型ではなく、 1 文字だけからなる文字列です。

5.3.3. スライス表記 (slicing)

スライス表記はシーケンスオブジェクト (文字列、タプルまたはリスト) におけるある範囲の要素を選択します。スライス表記は式として用いたり、代入や del 文の対象として用いたりできます。スライス表記の構文は以下のようになります:

slicing          ::=  simple_slicing | extended_slicing
simple_slicing   ::=  primary "[" short_slice "]"
extended_slicing ::=  primary "[" slice_list "]"
slice_list       ::=  slice_item ("," slice_item)* [","]
slice_item       ::=  expression | proper_slice | ellipsis
proper_slice     ::=  short_slice | long_slice
short_slice      ::=  [lower_bound] ":" [upper_bound]
long_slice       ::=  short_slice ":" [stride]
lower_bound      ::=  expression
upper_bound      ::=  expression
stride           ::=  expression
ellipsis         ::=  "..."

上記の形式的な構文法にはあいまいさがあります: 式リストに見えるものは、スライスリストにも見えるため、添字表記はスライス表記としても解釈されうるということです。この場合には、(スライスリストの評価結果が、適切なスライスや省略表記 (ellipsis) にならない場合)、スライス表記としての解釈よりも添字表記としての解釈の方が高い優先順位を持つように定義することで、構文法をより難解にすることなくあいまいさを取り除いています。同様に、スライスリストが厳密に一つだけの短いスライスで、末尾にカンマが続いていない場合、拡張スライスとしての解釈より、単純なスライスとしての解釈が優先されます。

単純なスライスに対する意味付けは以下のようになります。プライマリの値評価結果は、シーケンス型のオブジェクトでなければなりません。下境界および上境界を表す式がある場合、それらの値評価結果は整数でなくてはなりません; デフォルトの値は、それぞれゼロと sys.maxint です。どちらかの境界値が負である場合、シーケンスの長さが加算されます。こうして、スライスは i および j をそれぞれ指定した下境界、上境界として、インデクス ki <= k < j となる全ての要素を選択します。選択の結果、空のシーケンスになることもあります。 ij が有効なインデクス範囲の外側にある場合でも、エラーにはなりません (範囲外の要素は存在しないので、選択されないだけです)。

拡張スライスに対する意味付けは、以下のようになります。プライマリの値評価結果は、辞書型のオブジェクトでなければなりません。また、辞書は以下に述べるようにしてスライスリストから生成されたキーによってインデクス指定できなければなりません。スライスリストに少なくとも一つのカンマが含まれている場合、キーは各スライス要素を値変換したものからなるタプルになります; それ以外の場合、単一のスライス要素自体を値変換したものがキーになります。一個の式でできたスライス要素の変換は、その式になります。省略表記スライス要素の変換は、組み込みの Ellipsis オブジェクトになります。適切なスライスの変換は、スライスオブジェクト (標準型の階層 参照) で start, stop および step 属性は、それぞれ指定した下境界、上境界、およびとび幅 (stride) になります。式がない場合には None に置き換えられます。

5.3.4. 呼び出し (call)

呼び出しは、呼び出し可能オブジェクト (例えば function) を arguments の系列とともに呼び出します。系列は空の系列であってもかまいません:

call                 ::=  primary "(" [argument_list [","]
                          | expression genexpr_for] ")"
argument_list        ::=  positional_arguments ["," keyword_arguments]
                            ["," "*" expression] ["," keyword_arguments]
                            ["," "**" expression]
                          | keyword_arguments ["," "*" expression]
                            ["," "**" expression]
                          | "*" expression ["," keyword_arguments] ["," "**" expression]
                          | "**" expression
positional_arguments ::=  expression ("," expression)*
keyword_arguments    ::=  keyword_item ("," keyword_item)*
keyword_item         ::=  identifier "=" expression

固定引数やキーワード引数の後ろにカンマをつけてもかまいません。構文の意味付けに影響を及ぼすことはありません。

プライマリの値評価結果は、呼び出し可能オブジェクトでなければなりません (ユーザ定義関数、組み込み関数、組み込みオブジェクトのメソッド、クラスオブジェクト、クラスインスタンスのメソッド、そして特定のクラスインスタンス自体が呼び出し可能です; 拡張によって、その他の呼び出し可能オブジェクト型を定義することができます)。引数式は全て、呼び出しを試みる前に値評価されます。仮引数 (formal parameter) リストの構文については 関数定義 を参照してください。

キーワード引数が存在する場合、以下のようにして最初に固定引数 (positional argument) に変換されます。まず、値の入っていないスロットが仮引数に対して生成されます。N 個の固定引数がある場合、固定引数は先頭の N スロットに配置されます。次に、各キーワード引数について、識別子を使って対応するスロットを決定します (識別子が最初の仮引数パラメタ名と同じなら、最初のスロットを使う、といった具合です)。スロットがすでにすべて埋まっていたなら TypeError 例外が送出されます。それ以外の場合、引数値をスロットに埋めていきます。 (式が None であっても、その式でスロットを埋めます)。全ての引数が処理されたら、まだ埋められていないスロットをそれぞれに対応する関数定義時のデフォルト値で埋めます。(デフォルト値は、関数が定義されたときに一度だけ計算されます; 従って、リストや辞書のような変更可能なオブジェクトがデフォルト値として使われると、対応するスロットに引数を指定しない限り、このオブジェクトが全ての呼び出しから共有されます; このような状況は通常避けるべきです。) デフォルト値が指定されていない、値の埋められていないスロットが残っている場合 TypeError 例外が送出されます。そうでない場合、値の埋められたスロットからなるリストが呼び出しの引数として使われます。

CPython 実装の詳細: 実装では、名前を持たない固定引数を受け取る組み込み関数を提供するかもしれません。そういった引数がドキュメント化のために '名付けられて' いたとしても、実際には名付けられていないのでキーワードによって提供されません。 CPython では、C 言語で実装された関数の、名前を持たない固定引数を解析するために PyArg_ParseTuple() を使用します。

仮引数スロットの数よりも多くの固定引数がある場合、構文 *identifier を使って指定された仮引数がないかぎり、 TypeError 例外が送出されます; 仮引数 *identifier がある場合、この仮引数は余分な固定引数が入ったタプル (もしくは、余分な固定引数がない場合には空のタプル) を受け取ります。

キーワード引数のいずれかが仮引数名に対応しない場合、構文 **identifier を使って指定された仮引数がない限り、 TypeError 例外が送出されます; 仮引数 **identifier がある場合、この仮引数は余分なキーワード引数が入った (キーワードをキーとし、引数値をキーに対応する値とした) 辞書を受け取ります。余分なキーワード引数がない場合には、空の (新たな) 辞書を受け取ります。

関数呼び出しの際に構文 *expression が使われるなら、 expression の評価はシーケンスでなくてはなりません。このシーケンスの要素は、追加の固定引数のように扱われます; すなわち、固定引数 x1 ,…, xN があり、 expression の評価がシーケンス y1 ,…, yM であるなら、M+N 個の固定引数 x1 ,…, xN , y1 ,…, yM を使った呼び出しと同じになります。

*expression 構文はキーワード引数の 後ろ で指定しても良いですが、キーワード引数よりも で指定されたものとして処理されます (**expression 引数を指定したときの振る舞いは以下を参照)。従って、このようになります:

>>> def f(a, b):
...     print a, b
...
>>> f(b=1, *(2,))
2 1
>>> f(a=1, *(2,))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: f() got multiple values for keyword argument 'a'
>>> f(1, *(2,))
1 2

キーワード引数と *expression 構文を同じ呼び出しで一緒に使うことはあまりないので、実際に上記のような混乱が生じることはありません。

関数呼び出しで **expression 構文が使われた場合、 expression の値評価結果はマップ型でなければなりません。辞書の内容は追加のキーワード引数として扱われます。明示的なキーワード引数が expression 内のキーワードと重複した場合には TypeError 例外が送出されます。

*identifier**identifier 構文を使った仮引数は、固定引数スロットやキーワード引数名にすることができません。 (sublist) 構文を使った仮引数は、キーワード引数名には使えません; sublist は、リスト全体が一つの無名の引数スロットに対応しており、sublist 中の引数は、他の全てのパラメタに対する処理が終わった後に、通常のタプル形式の代入規則を使ってスロットに入れられます。

呼び出しを行うと、例外を送出しない限り、常に何らかの値を返します。 None を返す場合もあります。戻り値がどのように算出されるかは、呼び出し可能オブジェクトの形態によって異なります。

これが—

ユーザ定義関数:

関数のコードブロックに引数リストが渡され、実行されます。コードブロックは、まず仮引数を実引数に結合 (bind) します; この動作については 関数定義 で記述しています。コードブロックで return 文が実行される際に、関数呼び出しの戻り値 (return value) が決定されます。

組み込み関数またはメソッド:

結果はインタプリタに依存します; 組み込み関数やメソッドの詳細は 組み込み関数 を参照してください。

クラスオブジェクト:

そのクラスの新しいインスタンスが返されます。

クラスインスタンスメソッド:

対応するユーザ定義の関数が呼び出されます。このとき、呼び出し時の引数リストより一つ長い引数リストで呼び出されます: インスタンスが引数リストの先頭に追加されます。

クラスインスタンス:

クラスで __call__() メソッドが定義されていなければなりません; __call__() メソッドが呼び出された場合と同じ効果をもたらします。

5.4. べき乗演算 (power operator)

べき乗演算は、左側にある単項演算子よりも強い結合優先順位があります; 一方、右側にある単項演算子よりは低い結合優先順位になっています。構文は以下のようになります:

power ::=  primary ["**" u_expr]

従って、べき乗演算子と単項演算子からなる演算列が丸括弧で囲われていない場合、演算子は右から左へと評価されます (この場合は演算子の評価順序を強制しません。つまり -1**2-1 になります)。

べき乗演算子は、二つの引数で呼び出される組み込み関数 pow() と同じ意味付けを持っています。引数はまず共通の型に変換されます。結果の型は、型強制後の引数の型になります。

引数型を混合すると、二項算術演算における型強制規則が適用されます。整数や長整数の被演算子の場合、第二引数が負でない限り、結果は (型強制後の) 被演算子と同じになります; 第二引数が負の場合、全ての引数は浮動小数点型に変換され、浮動小数点型が返されます。例えば 10**2100 を返しますが、 10**-20.01 を返します。 (上述の仕様のうち、最後のものは Python 2.2 で追加されました。 Python 2.1 以前では、双方の引数が整数型で、第二引数が負の場合、例外が送出されていました。)

0.0 を負の数でべき乗すると ZeroDivisionError を送出します。負の数を小数でべき乗すると ValueError になります。

5.5. 単項算術演算とビット単位演算(unary arithmetic and bitwise operation)

全ての単項算術演算とビット単位演算は、同じ優先順位を持っています:

u_expr ::=  power | "-" u_expr | "+" u_expr | "~" u_expr

単項演算子 - (マイナス) は、引数となる数値の符号を反転 (negation) します。

単項演算子 + (プラス) は、数値引数を変更しません。

単項演算子 ~ (反転) は、整数または長整数の引数をビット単位反転 (bitwise invert) します。 x のビット単位反転は、 -(x+1) として定義されています。この演算子は整数にのみ適用されます。

上記の三つはいずれも、引数が正しい型でない場合には TypeError 例外が送出されます。

5.6. 二項算術演算 (binary arithmetic operation)

二項算術演算は、慣習的な優先順位を踏襲しています。演算子のいずれかは、特定の非数値型にも適用されるので注意してください。べき乗 (power) 演算子を除き、演算子には二つのレベル、すなわち乗算的 (multiplicatie) 演算子と加算的 (additie) 演算子しかありません:

m_expr ::=  u_expr | m_expr "*" u_expr | m_expr "//" u_expr | m_expr "/" u_expr
            | m_expr "%" u_expr
a_expr ::=  m_expr | a_expr "+" m_expr | a_expr "-" m_expr

* (乗算: multiplication) 演算は、引数間の積になります。引数の組は、双方ともに数値型であるか、片方が整数 (通常の整数または長整数) 型で他方がシーケンス型かのどちらかでなければなりません。前者の場合、数値は共通の型に変換された後乗算されます。後者の場合、シーケンスの繰り返し操作が行われます。繰り返し数を負にすると、空のシーケンスになります。

/ (除算: division) および // (切り捨て除算: floor division) は、引数間の商になります。数値引数はまず共通の型に変換されます。整数または長整数の除算結果は、同じ型の整数になります; この場合、結果は数学的な除算に関数 'floor' を適用したものになります。ゼロによる除算を行うと ZeroDivisionError 例外を送出します。

% (モジュロ: modulo) 演算は、第一引数を第二引数で除算したときの剰余になります。数値引数はまず共通の型に変換されます。右引数値がゼロの場合には ZeroDivisionError 例外が送出されます。引数値は浮動小数点でもよく。例えば 3.14%0.70.34 になります (3.144*0.7 + 0.34 だからです)。モジュロ演算子は常に第二引数と同じ符号 (またはゼロ) の結果になります; モジュロ演算の結果の絶対値は、常に第二引数の絶対値よりも小さくなります。 [2]

整数による除算演算やモジュロ演算は、恒等式: x == (x/y)*y + (x%y) と関係しています。整数除算やモジュロはまた、組み込み関数 divmod(): divmod(x, y) == (x/y, x%y) と関係しています。これらの恒等関係は浮動小数点の場合には維持されません; x/yfloor(x/y)floor(x/y) - 1 に置き換えられた場合、これらの恒等式は近似性を維持します。 [3]

数値に対するモジュロ演算の実行に加えて % 演算子は文字列 (string) とユニコードオブジェクトにオーバーロードされ、文字列の書式化 (文字列の挿入としても知られる) を行います。文字列の書式化の構文は Python ライブラリリファレンス 文字列フォーマット操作 節を参照してください。

バージョン 2.3 で撤廃: 切り捨て除算演算子、モジュロ演算子、および divmod() 関数は、複素数に対してはもはや定義されていません。目的に合うならば、代わりに abs() を使って浮動小数点に変換してください。

+ (加算) 演算は、引数を加算した値を返します。引数は双方とも数値型か、双方とも同じ型のシーケンスでなければなりません。前者の場合、数値は共通の型に変換され、加算されます。後者の場合、シーケンスは結合 (concatenate) されます。

- (減算) 演算は、引数間で減算を行った値を返します。数値引数はまず共通の型に変換されます。

5.7. シフト演算 (shifting operation)

シフト演算は、算術演算よりも低い優先順位を持っています:

shift_expr ::=  a_expr | shift_expr ( "<<" | ">>" ) a_expr

シフトの演算子は整数または長整数を引数にとります。引数は共通の型に変換されます。シフト演算では、最初の引数を二つ目の引数に応じたビット数だけ、左または右にビットシフトします。

n ビットの右シフトは pow(2,n) による除算として定義されています。 n ビットの左シフトは pow(2,n) による乗算として定義されます。負のビット数でシフトを行うと ValueError 例外を送出します。

注釈

現在の実装では、右辺被演算子は最大でも sys.maxsize でなければなりません。右辺被演算子が sys.maxsize よりも大きいと、 OverflowError 例外が送出されます。

5.8. ビット単位演算の二項演算 (binary bitwise operation)

以下の三つのビット単位演算には、それぞれ異なる優先順位レベルがあります:

and_expr ::=  shift_expr | and_expr "&" shift_expr
xor_expr ::=  and_expr | xor_expr "^" and_expr
or_expr  ::=  xor_expr | or_expr "|" xor_expr

& 演算子は、引数間でビット単位の AND をとった値になります。引数は整数または長整数でなければなりません。引数は共通の型に変換されます。

^ 演算子は、引数間でビット単位の XOR (排他的 OR) をとった値になります。引数は整数または長整数でなければなりません。引数は共通の型に変換されます。

| 演算子は、引数間でビット単位の OR (非排他的 OR) をとった値になります。引数は整数または長整数でなければなりません。引数は共通の型に変換されます。

5.9. 比較

C 言語と違って、Python における比較演算子は同じ優先順位をもっており、全ての算術演算子、シフト演算子、ビット単位演算子よりも低くなっています。また a < b < c が数学で伝統的に用いられているのと同じ解釈になる点も C 言語と違います:

comparison    ::=  or_expr ( comp_operator or_expr )*
comp_operator ::=  "<" | ">" | "==" | ">=" | "<=" | "<>" | "!="
                   | "is" ["not"] | ["not"] "in"

比較演算の結果はブール値: True または False になります。

比較はいくらでも連鎖することができます。例えば x < y <= zx < y and y <= z と等価になります。ただしこの場合、前者では y はただ一度だけ評価される点が異なります (どちらの場合でも、 x < y が偽になると z の値はまったく評価されません)。

形式的には、 a, b, c, …, y, z が式で op1, op2, …, opN が比較演算子である場合、 a op1 b op2 c ... y opN za op1 b and b op2 c and ... y opN z と等価になります。ただし、前者では各式は多くても一度しか評価されません。

a op1 b op2 c と書いた場合、 a から c までの範囲にあるかどうかのテストを指すのではないことに注意してください。例えば x < y > z は (きれいな書き方ではありませんが) 完全に正しい文法です。

<>!= の二つの形式は等価です; C との整合性を持たせるためには != を推奨します; 以下で != について触れている部分では <> を使うこともできます。 <> のような書き方は、現在では古い書き方とみなされています。

5.9.1. 値の比較

演算子 <, >, ==, >=, <=, および != は2つのオブジェクトの値を比較します。オブジェクトが同じ型を持つ必要はりません。

オブジェクト、値、および型 の章では、オブジェクトは (型や同一性に加えて) 値を持つことを述べています。オブジェクトの値は Python ではやや抽象的な概念です: 例えば、オブジェクトの値にアクセスする正統な方法はありません。また、その全てのデータ属性から構成されるなどの特定の方法で、オブジェクトの値を構築する必要性もありません。比較演算子は、オブジェクトの値とは何かについての特定の概念を実装しています。この比較の実装によって、間接的にオブジェクトの値を定義している考えることもできます。

基本的なカスタマイズ で解説されているように、型を使って __cmp__() メソッドや rich comparison methods である __lt__() などのメソッドを実装することで、 比較の振る舞いをカスタマイズできます。

等価性比較 (== および !=) のデフォルトの振る舞いは、オブジェクトの同一性に基づいています。従って、同一のインスタンスの等価性比較は等価となり、同一でないインスタンスの等価性比較は等価でないとなります。デフォルトの振る舞いをこのようにしたのは、全てのオブジェクトを反射的 (reflexive つまり x is y ならば x == y) なものにしたかったからです。

デフォルトの順序比較 (<, >, <=, >=) は一貫性はありますがいい加減な順序です。

(このような比較演算の変則的な定義は、ソートのような操作や in および not in といった演算子の定義を単純化するためのものです。将来、異なる型のオブジェクト間における比較規則は変更されるかもしれません。)

同一でないインスタンスは常に等価でないとする等価性比較のデフォルトの振る舞いは、型が必要とするオブジェクトの値や値に基づいた等価性の実用的な定義とは対照的に思えるでしょう。そのような型では比較の振る舞いをカスタマイズする必要が出てきて、実際にたくさんの組み込み型でそれが行われています。

次のリストでは、最重要の組み込み型の比較の振る舞いを解説しています。

  • いくつかの組み込みの数値型 (数値型 int, float, long, complex) と標準ライブラリの型 fractions.Fraction および decimal.Decimal は、同じ型や別の型どうしで比較できますが、複素数では順序比較がサポートされていないという制限があります。関わる型の制限の範囲内では、精度のロス無しに数学的に (アルゴリズム的に) 正しい比較が行われます。

  • 文字列 (str もしくは unicode のインスタンス) では、数値的な同等性 (組み込み関数 ord() の結果) を使い、辞書式の比較を行います。 [4] 8 bit 文字列と Unicode 文字列を比較するときは、8 bit 文字列は Unicode へ変換されます。変換が失敗した場合は、その文字列は等価でないと見なされます。

  • tuplelist のインスタンスは同じ型どうしでしか比較できません。異なる型どうしでの等価性比較は等価でないとなり、異なる型どうしでの順序比較はいい加減な順序になります。

    これらのシーケンスでは、要素の反射性があるものとして、個々の対応する要素の比較を使って辞書式の比較が行われます。

    要素の反射性があるものとされると、コレクションの比較では、コレクションの要素 x に対して x == x が常に真だと仮定します。この仮定に基づいて、最初に要素の同一性が比較され、同一でない要素どうしに対してのみ要素の比較が行われます。この手法は、比較される要素が反射的な場合、厳密な要素比較と同じ結果をもたらします。反射的でない要素では、厳密な要素比較と異なる結果になります。

    組み込みのコレクションどうしの辞書式比較は次のように動作します:

    • 比較の結果が等価となる2つのコレクションは、同じ型、同じ長さ、対応する要素どうしの比較の結果が等価でなければなりません (例えば、 [1,2] == (1,2) は型が同じでないので偽です)。
    • コレクションの順序は、最初の等価でない要素の順序と同じになります (例えば、 cmp([1,2,x], [1,2,y])cmp(x,y) と同じ返り値になります)。対応する要素が存在しない場合、短い方のコレクションが順序として先となります (例えば、 [1,2] < [1,2,3] は真です)。
  • マッピング (dict のインスタンス) の比較の結果が等価となるのは、同じ (key, value) を持っているときかつそのときに限ります。キーと値の等価性比較では反射性が強制されます。

    等価性評価以外の結果は一貫したやりかたで解決されるか、定義されないかのいずれかです。 [5]

  • その他のほとんどの組み込み型のオブジェクト比較では、同じオブジェクトでないかぎり等価にはなりません; あるオブジェクトの他のオブジェクトに対する大小関係は任意に決定され、一つのプログラムの実行中は一貫したものとなります。

比較の振る舞いをカスタマイズしたユーザ定義クラスは、可能なら次の一貫性の規則に従う必要があります:

  • 等価比較は反射的でなければなりません。つまり、同一のオブジェクトは等しくなければなりません:

    x is y は暗黙的に x == y

  • 比較は対称でなければなりません。つまり、以下の式の結果は同じでなければなりません:

    x == yy == x

    x != yy != x

    x < yy > x

    x <= yy >= x

  • 比較は推移的でなければなりません。以下の (包括的でない) 例がその説明です:

    x > y and y > z は暗黙的に x > z

    x < y and y <= z は暗黙的に x < z

  • 比較の逆はブールの否定でなければなりません。つまり、以下の式の結果は同じでなければなりません:

    x == ynot x != y

    x < ynot x >= y (全順序の場合)

    x > ynot x <= y (全順序の場合)

    最後の2式は全順序の集まりに適用されます (たとえばシーケンスには適用されますがセットやマッピングには適用されません)。 total_ordering() デコレータも参照してください。

  • hash() の結果は等価性と一貫している必要があります。等価なオブジェクトどうしは同じハッシュ値を持つか、ハッシュ値が計算できないものとされる必要があります。

Python はこれらの一貫性の規則を強制しません。

5.9.2. 帰属検査演算

演算子 in および not in は所属関係を調べます。 x in s の評価は、 xs の要素であれば True となり、そうでなければ False となります。 x not in sx in s の否定を返します。すべての組み込みのシーケンスと集合型に加えて、辞書も、 in を辞書が与えられたキーを持っているかを調べるものとしてサポートしています。リスト、タプル、集合、凍結集合、辞書、あるいは collections.deque のようなコンテナ型について、式 x in yany(x is e or x == e for e in y) と等価です。

文字列やバイト列型については、 x in yxy の部分文字列であるとき、かつそのときに限り True になります。これは y.find(x) != -1 と等価です。空文字列は、他の任意の文字列の部分文字列とみなされます。従って "" in "abc"True を返すことになります。

__contains__() メソッドを実装したユーザ定義クラスでは、 y.__contains__(x) の返り値が真となる場合に x in y の返り値は True となり、そうでない場合は False となります。

__contains__() を定義していないが __iter__() は定義しているユーザ定義クラスでは、 x == z となるようなある値 zy 内にわたる反復で生成された場合、 x in yTrue となります。反復処理の途中で例外が送出された場合、 in が例外を発生させたように振る舞います。

最終的には、旧式の反復プロトコルの実行を試みます、もし __getitem__() を定義しているようなユーザ定義クラスでは、 x in yx == y[i] となるような非負の整数インデクス i が存在するとき、かつそのときにかぎり True となります。インデクス i が負である場合に IndexError 例外が送出されることはありません。 (別の何らかの例外が送出された場合、例外は in から送出されたかのようになります)。

演算子 not inin の真値を反転した値として定義されています。

5.9.3. 同一性の比較

演算子 is および is not は、オブジェクトのアイデンティティに対するテストを行います: x is y は、 xy が同じオブジェクトを指すとき、かつそのときに限り真になります。 x is not yis の真値を反転したものになります。 [6]

5.10. ブール演算 (boolean operation)

or_test  ::=  and_test | or_test "or" and_test
and_test ::=  not_test | and_test "and" not_test
not_test ::=  comparison | "not" not_test

ブール演算のコンテキストや、式が制御フロー文中で使われる最には、以下の値: FalseNone 、すべての型における数値のゼロ、空の文字列とコンテナ (文字列、タプル、リスト、辞書、set、frozenset を含む) は偽 (false) であると解釈されます。それ以外の値は真 (true) であると解釈されます。 (この振る舞いを変更する方法については特殊メソッド __nonzero__() を参照してください)

演算子 not は、引数が偽である場合には True を、それ以外の場合には False になります。

x and y は、まず x を評価します; x が偽なら x の値を返します; それ以外の場合には、 y の値を評価し、その結果を返します。

x or y は、まず x を評価します; x が真なら x の値を返します; それ以外の場合には、 y の値を評価し、その結果を返します。

(andnot も、返す値を FalseTrue に制限するのではなく、最後に評価した引数の値を返すので注意してください。この仕様は、例えば s を文字列として s が空文字列の場合にデフォルトの値に置き換えるような場合に、 s or 'foo' と書くと期待通りの値になるために便利なことがあります。 not は、式の値でなく独自に値を作成して返すので、引数と同じ型の値を返すような処理に煩わされることはありません。例えば、 not 'foo' は、 '' ではなく False になります)

5.11. 条件演算 (Conditional Expressions)

バージョン 2.5 で追加.

conditional_expression ::=  or_test ["if" or_test "else" expression]
expression             ::=  conditional_expression | lambda_expr

条件演算式 (しばしば、"三項演算子" と呼ばれます) は最も優先度が低いPython の操作です。

x if C else y という式は最初に条件 C (x では ありません) を評価します; C が true の場合 x が評価され値が返されます; それ以外の場合には y が評価され返されます。

条件演算に関してより詳しくは PEP 308 を参照してください。

5.12. ラムダ (lambda)

lambda_expr     ::=  "lambda" [parameter_list]: expression
old_lambda_expr ::=  "lambda" [parameter_list]: old_expression

ラムダ式 (lambda expression または lambda forms) は構文的には式と同じ位置づけになります。ラムダは無名関数を作成できる省略記法です; 式 lambda arguments: expression は関数オブジェクトになります。ラムダで表される無名オブジェクトは以下の関数オブジェクト同様に動作します。:

def name(arguments):
    return expression

パラメータの構文の一覧は 関数定義 を参照してください。ラムダ式で作成された関数は命令文を含むことができない点に注意してください。

5.13. 式のリスト

expression_list ::=  expression ( "," expression )* [","]

少なくとも一つのカンマを含む式のリストは、タプルになります。タプルの長さは、リスト中の式の数に等しくなります。リスト中の式は左から右へと順に評価されます。

単一要素のタプル (別名 単集合 (singleton) ) を作りたければ、末尾にカンマが必要です。単一の式だけで、末尾にカンマをつけない場合には、タプルではなくその式の値になります (空のタプルを作りたいなら、中身が空の丸括弧ペア: () を使います。)

5.14. 評価順序

Python は、式を左から右へと順に評価してゆきます。ただし、代入式を評価する最には、代入演算子の右側項が左側項よりも先に評価されるので注意してください。

以下に示す実行文の各行での評価順序は、添え字の数字順序と同じになります:

expr1, expr2, expr3, expr4
(expr1, expr2, expr3, expr4)
{expr1: expr2, expr3: expr4}
expr1 + expr2 * (expr3 - expr4)
expr1(expr2, expr3, *expr4, **expr5)
expr3, expr4 = expr1, expr2

5.15. 演算子の優先順位

以下の表は、Python における演算子を、優先順位の最も低い (結合度が最も低い) ものから最も高い (結合度が最も高い) ものの順に並べたものです。同じボックス内に示された演算子は同じ優先順位を持ちます。演算子の文法が示されていないかぎり、演算子は全て二項演算子です。同じボックス内の演算子は、左から右へとグループ化されます (値のテストを含む比較演算子を除きます。比較演算子は、左から右に連鎖します — 比較 を参照してください。また、べき乗演算子も除きます。べき乗演算子は右から左にグループ化されます)。

演算子 説明
lambda ラムダ式
ifelse 条件演算
or ブール演算 OR
and ブール演算 AND
not x ブール演算 NOT
in, not in, is, is not, <, <=, >, >=, <>, !=, == 帰属や同一性のテストを含む比較
| ビット単位 OR
^ ビット単位 XOR
& ビット単位 AND
<<, >> シフト演算
+, - 加算および減算
*, /, //, % 乗算、除算、剰余 [7]
+x, -x, ~x 正符号、負符号、ビット単位 NOT
** べき乗 [8]
x[index], x[index:index], x(arguments...), x.attribute 添字指定、スライス操作属性参照
(expressions...), [expressions...], {key: value...}, `expressions...` 式結合またはタプル表現、リスト表現、辞書表現、文字列への型変換

注記

[1]Python 2.3 以降のリスト内包は for の中で使う制御変数を内包表記内のスコープに「リーク」します。しかし、この挙動は廃止予定です。Python 3 ではこの挙動に依存したコードは動作しなくなります。
[2]abs(x%y) < abs(y) は数学的には真となりますが、浮動小数点に対する演算の場合には、値丸め (roundoff) のために数値計算的に真にならない場合があります。例えば、Python の浮動小数点型が IEEE754 倍精度数型になっているプラットフォームを仮定すると、 -1e-100 % 1e1001e100 と同じ符号になるはずなのに、計算結果は -1e-100 + 1e100 となります。これは数値計算的には厳密に 1e100 と等価です。関数 math.fmod() は、最初の引数と符号が一致するような値を返すので、上記の場合には -1e-100 を返します。どちらのアプローチが適切かは、アプリケーションに依存します。
[3]x が y の整数倍に非常に近い場合、丸め誤差によって floor(x/y)(x-x%y)/y よりも大きな値になる可能性があります。そのような場合、 Python は divmod(x,y)[0] * y + x % yx に非常に近くなるという関係を保つために、後者の値を返します。
[4]

Unicode 標準では、 コードポイント (code point) (例えば、U+0041) と 抽象文字 (abstract character) (例えば、"LATIN CAPITAL LETTER A") を区別します。 Unicode のほとんどの抽象文字は 1 つのコードポイントだけを使って表現されますが、複数のコードポイントの列を使っても表現できる抽象文字もたくさんあります。例えば、抽象文字 "LATIN CAPITAL LETTER C WITH CEDILLA" はコード位置 U+00C7 にある 合成済み文字 (precomposed character) 1 つだけでも表現できますし、コード位置 U+0043 (LATIN CAPITAL LETTER C) にある 基底文字 (base character) の後ろに、コード位置 U+0327 (COMBINING CEDILLA) にある 結合文字 (combining character) が続く列としても表現できます。

Unicode 文字列の比較操作は Unicode のコードポイントのレベルで行われます。これは人間にとっては直感的ではないかもしれません。例えば、 u"\u00C7" == u"\u0043\u0327" は、どちらの文字も同じ抽象文字 "LATIN CAPITAL LETTER C WITH CEDILLA" を表現しているにもかかわらず、その結果は False となります。

抽象文字のレベルで (つまり、人間にとって直感的な方法で) 文字列を比較するには unicodedata.normalize() を使ってください。

[5]Python の初期のバージョンでは、ソートされた (key, value) のリストに対して辞書的な比較を行っていましたが、これは等価性の計算のようなよくある操作を実現するには非常にコストの高い操作でした。もっと以前のバージョンの Python では、辞書はアイデンティティだけで比較されていました。しかしこの仕様は、 {} との比較によって辞書が空であるか確かめられると期待していた人々を混乱させていました。
[6]自動的なガベージコレクション、フリーリスト、ディスクリプタの動的特性のために、インスタンスメソッドや定数の比較を行うようなときに is 演算子の利用は、一見すると普通ではない振る舞いだと気付くかもしれません。詳細はそれぞれのドキュメントを確認してください。
[7]% 演算子は文字列フォーマットにも使われ、同じ優先順位が当てはまります。
[8]べき乗演算子 ** はその右側にある単項演算子かビット単位演算子よりも優先して束縛されます。つまり 2**-10.5 になります。