式 (expression)
この章では、Python の式における個々の要素の意味について解説します。
表記法に関する注意: この章と以降の章での拡張BNF (extended BNF) 表記は、字句解析規則ではなく、構文規則を記述するために用いられています。ある構文規則 (のある表現方法) が、以下の形式
name ::= othername
で記述されていて、この構文特有の意味付け (semantics) が記述されていない場合、 name
の形式をとる構文の意味付けは othername の意味付けと同じになります。
算術変換 (arithmetic conversion)
以下の算術演算子の記述で、「数値引数は共通の型に変換されます」と書かれている場合、引数は 型強制規則 (coercion rule) に記載されている型強制規則に基づいて型強制されます。引数がいずれも標準の数値型である場合、以下の型強制が適用されます:
- 片方の引数が複素数型であれば、他方は複素数型に変換されます;
- それ以外の場合で、片方の引数が浮動小数点数であれば、他方は浮動小数点型に変換されます;
- それ以外の場合で、片方の引数が長整数型であれば、他方は長整数型に変換されます;
- それ以外の場合で、両方の引数が通常の整数型であれば、変換の必要はありません。
特定の演算子 (文字列を左引数とする ‘%’ 演算子など) では、さらに別の規則が適用されます。拡張をおこなうことで、個々の演算子に対する型強制を定義できます。
アトム、原子的要素 (atom)
アトム (原子的要素: atom) は、式を構成する基本単位です。もっとも単純なアトムは、識別子またはリテラルになります。逆クオートや丸括弧、波括弧、または角括弧で囲われた形式 (form) もまた、文法的にはアトムに分類されます。アトムの構文定義は以下のようになります:
atom ::= identifier | literal | enclosure
enclosure ::= parenth_form | list_display
| generator_expression | dict_display | set_display
| string_conversion | yield_atom
識別子 (identifier、または名前 (name))
アトムの形になっている識別子 (identifier) は名前 (name) です。字句定義については 識別子 (identifier) およびキーワード (keyword) 節を、名前付けや束縛については 名前づけと束縛 (naming and binding) 節を参照してください。
名前があるオブジェクトに束縛されている場合、名前アトムを評価するとそのオブジェクトになります。名前が束縛されていない場合、アトムを評価しようとすると NameError 例外を送出します。
プライベートな名前の難号化 (mangling): クラス定義内にテキストの形で書かれた識別子で、二つ以上のアンダースコアから始まり、末尾が二つ以上のアンダースコアになっていないものは、そのクラスの プライベートな名前 (private name) とみなされます。プライベートな名前は、コードが生成される前に、より長い形式の名前に変換されます。この変換では、クラス名の先頭にあるアンダースコアを全てはぎとり、先頭にアンダースコアを一つ挿入して、名前の前に付加します。例えば、クラス Ham 内の識別子 __spam は、
_Ham__spam に変換されます。変換は識別子が使われている構文的コンテキストとは独立しています。変換された名前が非常に長い (255 文字以上)
の場合には、実装によっては名前の切り詰めが起きるかもしれません。クラス名がアンダースコアだけから成り立つ場合には、変換は行われません。
リテラル
Python では、文字列リテラルと、様々な数値リテラルをサポートしています:
literal ::= stringliteral | integer | longinteger
| floatnumber | imagnumber
リテラルを評価すると、指定した型 (文字列、整数、長整数、浮動小数点数、複素数) の指定した値を持つオブジェクトになります。浮動小数点や虚数 (複素数)
リテラルの場合、値は近似値になる場合があります。詳しくは リテラル (literal) を参照してください。リテラルは全て変更不能なデータ型に対応します。このため、オブジェクトのアイデンティティはオブジェクトの値ほど重要ではありません。同じ値を持つ複数のリテラルを評価した場合、(それらのリテラルがプログラムの同じ場所由来のものであっても、そうでなくても)
同じオブジェクトを指しているか、まったく同じ値を持つ別のオブジェクトになります。
集合と辞書の表現
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 節からなります。この場合、新たなコンテナの各要素は、各々の for や if
節を、左から右にネストしたブロックとみなして実行し、ネストの最内のブロックに到達する度に式を評価することで作成されたものになります。
なお、これらの内包表記は別のスコープで実行されるので、対象のリスト内で代入された名前が外側のスコープに “漏れる” ことはありません。
ジェネレータ式
ジェネレータ式 (generator expression) とは、丸括弧を使ったコンパクトなジェネレータ表記法です:
generator_expression ::= "(" expression comp_for ")"
ジェネレータ式は新たなジェネレータオブジェクトを与えます。この構文は内包表記とほぼ同じですが、角括弧や波括弧ではなく、丸括弧で囲まれます。
ジェネレータ式で使われる変数は、ジェネレータオブジェクトに
next() メソッドが呼び出されたときに遅延評価されます (通常のジェネレータと同じ流儀です)。しかし、最も左に位置する
for 節は直ちに評価されるため、そこで生じたエラーは、ジェネレータ式を扱うコードで起こりえる他のエラーの前に現れることがあります。その後に続く for 節は、その前の
for ループに依存しているため、直ちには評価されません。例: (x*y for x in range(10) for y in bar(x))
関数の唯一の引数として渡す場合には、丸括弧を省略できます。詳しくは 呼び出し (call) 節を参照してください。
辞書表現
辞書表現は、波括弧で囲われた、キーと値のペアからなる系列です。系列は空の系列であってもかまいません:
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 でなければなりません。) 重複するキー間で衝突が起きても、衝突が検出されることはありません; あるキーに対して、最後に渡されたデータ
(プログラムテキスト上では、辞書表記の最も右側値となるもの) が使われます。
集合表現
集合表現は波括弧で表され、キーと値を分けるコロンがないことで辞書表現と区別されます:
set_display ::= "{" (expression_list | comprehension) "}"
集合表示は、一連の式または内包表記によって指定された内容の、ミュータブルな集合オブジェクトを与えます。カンマ区切りの一連の式が与えられたときは、その要素は左から右へ順に評価され、集合オブジェクトに加えられます。内包表記が与えられたときは、内包表記の結果となる要素で集合が構成されます。
空集合は {} で構成できません。このリテラルは空の辞書を構成します。
文字列変換
文字列変換は、逆クオート (reverse quite, 別名バッククオート: backward quote) で囲われた式のリストです:
string_conversion ::= "'" expression_list "'"
文字列変換は、逆クオート内の式リストを評価して、評価結果のオブジェクトを各オブジェクトの型特有の規則に従って文字列に変換します。
オブジェクトが文字列、数値、 None か、それらの型のオブジェクトのみを含むタプル、リストまたは辞書の場合、評価結果の文字列は有効な Python
式となり、組み込み関数 eval() に渡した場合に同じ値となります (浮動小数点が含まれている場合には近似値の場合もあります)。
(特に、文字列を変換すると、値を安全に出力するために文字列の両側にクオートが付けられ、”変 (funny) な” 文字はエスケープシーケンスに変換されます。)
再帰的な構造をもつオブジェクト (例えば自分自身を直接または間接的に含むリストや辞書) では ... を使って再帰的参照であることが示され、オブジェクトの評価結果は eval() に渡しても等価な値を得ることができません (SyntaxError が送出されます)。
組み込み関数 repr() は、括弧内の引数に対して、逆クオート表記で囲われた中身と全く同じ変換を実行します。組み込み関数
str() は似たような動作をしますが、もっとユーザフレンドリな変換になります。
Yield 式
yield_atom ::= "(" yield_expression ")"
yield_expression ::= "yield" [expression_list]
バージョン 2.5 で追加.
yield 式はジェネレータ関数を定義するときにその関数の内部でのみ使用されます。関数内で yield 式を使用すると、普通の関数ではなくジェネレータ関数が作成されます。
ジェネレータ関数が呼び出されるとき、ジェネレータとしてのイテレータを返します。そのジェネレータはジェネレータ関数の実行を制御します。ジェネレータのメソッドが呼び出されるときに実行が開始されます。メソッドを呼び出すと、実行は yield の最初の位置まで処理されて一時停止します。そして、ジェネレータの呼び出し元へ expression_list の値を返します。ここで言う一時停止とは、ローカル変数の束縛、命令ポインタや内部の評価スタックを含めたローカルの全ての状態が保持されることを指します。再度、ジェネレータのメソッドを呼び出して実行を再開するとき、そのジェネレータ関数はまさに yield 式がただの外部呼び出しであったかのように処理が継続されます。再開した後の yield 式の値は実行を再開するメソッドに依存します。
これまで説明した内容から、ジェネレータ関数はコルーチンにとてもよく似ています。ジェネレータ関数は何度も生成し、1つ以上のエントリポイントを持ち、その実行は一時停止されます。ジェネレータ関数は yield した後で実行の継続を制御できないことが唯一の違いです。その制御は常にジェネレータの呼び出し元へ移されます。
以下のジェネレータメソッドはジェネレータ関数の実行を制御するために使用されます。
-
generator.next()
ジェネレータ関数の実行を開始する、または最後に yield 式が実行された位置から再開します。ジェネレータ関数が next() メソッドで再開されるとき、カレントの yield は常に None に対して評価されます。それから実行は、次の yield 式の位置まで継続されて、再度そのジェネレータは一時停止します。そして expression_list の値が
next() の呼び出し元へ返されます。ジェネレータが値を生成することなく終了すると 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 を拡張する提案です。
一次語 (primary)
一次語は、言語において最も結合の強い操作を表します。文法は以下のようになります:
primary ::= atom | attributeref | subscription | slicing | call
属性参照
属性参照は、一次語の後ろにピリオドと名前を連ねたものです:
attributeref ::= primary "." identifier
一次語の値評価結果は、例えばモジュール、リスト、インスタンスといった、属性参照をサポートする型でなければなりません。オブジェクトは次に、指定した名前が識別子名となっているような属性を生成するよう問い合わせされます。問い合わせた属性が得られない場合、例外
AttributeError が送出されます。それ以外の場合、オブジェクトは属性オブジェクトの型と値を決定し、生成して返します。同じ属性参照を複数回評価したとき、互いに異なる属性オブジェクトになることがあります。
添字表記 (subscription)
添字表記は、シーケンス (文字列、タプルまたはリスト) やマップ (辞書) オブジェクトから、要素を一つ選択します:
subscription ::= primary "[" expression_list "]"
一次語の値評価結果は、シーケンス型かマップ型のオブジェクトでなければなりません。
一次語がマップであれば、式リストの値評価結果はマップ内のいずれかのキー値に相当するオブジェクトにならなければなりません。添字表記は、そのキーに対応するマップ内の値 (value) を選択します。 (式リストの要素が単独である場合を除き、式リストはタプルでなければなりません。)
一次語がシーケンスの場合、式 (リスト) の値評価結果は (通常の) 整数でなければなりません。値が負の場合、シーケンスの長さが加算されます
(x[-1] が x の最後の要素を指すことになります)。加算結果はシーケンス内の要素数よりも小さな非負の整数とならなければなりません。添字表記は、添字と同じシーケンス中の (ゼロから数えた) インデクスを持つ要素を選択します。
文字列型の要素は文字 (character) です。文字は個別の型ではなく、 1 文字だけからなる文字列です。
スライス表記 (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 をそれぞれ指定した下境界、上境界として、インデクス k が i <= k < j となる全ての要素を選択します。選択の結果、空のシーケンスになることもあります。 i や j が有効なインデクス範囲の外側にある場合でも、エラーにはなりません (範囲外の要素は存在しないので、選択されないだけです)。
拡張スライスに対する意味付けは、以下のようになります。一次語の値評価結果は、辞書型のオブジェクトでなければなりません。また、辞書は以下に述べるようにしてスライスリストから生成されたキーによってインデクス指定できなければなりません。スライスリストに少なくとも一つのカンマが含まれている場合、キーは各スライス要素を値変換したものからなるタプルになります;
それ以外の場合、単一のスライス要素自体を値変換したものがキーになります。一個の式でできたスライス要素の変換は、その式になります。省略表記スライス要素の変換は、組み込みの Ellipsis オブジェクトになります。適切なスライスの変換は、スライスオブジェクト
(標準型の階層 参照) で start, stop および step
属性は、それぞれ指定した下境界、上境界、およびとび幅 (stride) になります。式がない場合には None に置き換えられます。
呼び出し (call)
呼び出し (call) は、呼び出し可能オブジェクト (callable object, 例えば関数など)
を、引数列とともに呼び出します。引数列は空のシーケンスでもかまいません:
call ::= primary "(" [argument_list [","]
| expression genexpr_for] ")"
argument_list ::= positional_arguments ["," keyword_arguments]
["," "*" expression] ["," keyword_arguments]
["," "**" expression]
| keyword_arguments ["," "*" expression]
["," "**" expression]
| "*" expression ["," "*" expression] ["," "**" 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 implementation detail: 実際の実装では、名前を持たない固定引数を受け取る組み込み関数を提供するかもしれません。そういった組み込み関数がドキュメント化の目的で ‘名前’ を設けていたとしても、実際には持っていないのでキーワードによって提供されません。
CPython では、C 言語で実装された関数の名前を持たない固定引数を解析するために
PyArg_ParseTuple() を使用します。
仮引数スロットの数よりも多くの固定引数がある場合、構文 *identifier を使って指定された仮引数がないかぎり、
TypeError 例外が送出されます; 仮引数 *identifier がある場合、この仮引数は余分な固定引数が入ったタプル
(もしくは、余分な固定引数がない場合には空のタプル) を受け取ります。
キーワード引数のいずれかが仮引数名に対応しない場合、構文 **identifier を使って指定された仮引数がない限り、
TypeError 例外が送出されます; 仮引数 **identifier がある場合、この仮引数は余分なキーワード引数が入った
(キーワードをキーとし、引数値をキーに対応する値とした) 辞書を受け取ります。余分なキーワード引数がない場合には、空の (新たな) 辞書を受け取ります。
関数呼び出しの際に *expression 構文が使われる場合、 expression の値評価結果はシーケンスでなくてはなりません。このシーケンスの要素は、追加の固定引数のように扱われます; すなわち、固定引数 x1 ,..., xN と、 y1 ,..., yM になるシーケンス
expression を使った場合、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 ?
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__()
メソッドが呼び出された場合と同じ効果をもたらします。
べき乗演算 (power operator)
べき乗演算は、左側にある単項演算子よりも強い結合優先順位があります; 一方、右側にある単項演算子よりは低い結合優先順位になっています。構文は以下のようになります:
power ::= primary ["**" u_expr]
従って、べき乗演算子と単項演算子からなる演算列が丸括弧で囲われていない場合、演算子は右から左へと評価されます (この場合は演算子の評価順序を強制しません。つまり -1**2 は -1 になります)。
べき乗演算子は、二つの引数で呼び出される組み込み関数 pow() と同じ意味付けを持っています。引数はまず共通の型に変換されます。結果の型は、型強制後の引数の型になります。
引数型を混合すると、二項算術演算における型強制規則が適用されます。整数や長整数の被演算子の場合、第二引数が負でない限り、結果は (型強制後の)
被演算子と同じになります; 第二引数が負の場合、全ての引数は浮動小数点型に変換され、浮動小数点型が返されます。例えば 10**2 は 100
を返しますが、 10**-2 は 0.01 を返します。 (上述の仕様のうち、最後のものは Python 2.2 で追加されました。
Python 2.1 以前では、双方の引数が整数型で、第二引数が負の場合、例外が送出されていました。)
0.0 を負の数でべき乗すると ZeroDivisionError を送出します。負の数を小数でべき乗すると
ValueError になります。
単項算術演算とビット単位演算(unary arithmetic and bitwise operation)
全ての単項算術演算とビット単位演算は、同じ優先順位を持っています:
u_expr ::= power | "-" u_expr | "+" u_expr | "~" u_expr
単項演算子 - (マイナス) は、引数となる数値の符号を反転 (invert) します。
単項演算子 + (プラス) は、数値引数を変更しません。
単項演算子 ~ (反転) は、整数または長整数の引数をビット単位反転 (bitwise invert) します。 x のビット単位反転は、
-(x+1) として定義されています。この演算子は整数にのみ適用されます。
上記の三つはいずれも、引数が正しい型でない場合には TypeError 例外が送出されます。
二項算術演算 (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.7
は 0.34 になります (3.14 は 4*0.7 + 0.34 だからです)。モジュロ演算子は常に第二引数と同じ符号
(またはゼロ) の結果になります; モジュロ演算の結果の絶対値は、常に第二引数の絶対値よりも小さくなります。
整数による除算演算やモジュロ演算は、恒等式: x == (x/y)*y + (x%y) と関係しています。整数除算やモジュロはまた、組み込み関数
divmod(): divmod(x, y) == (x/y, x%y) と関係しています。これらの恒等関係は浮動小数点の場合には維持されません; x/y が floor(x/y) や floor(x/y) - 1 に置き換えられた場合、これらの恒等式は近似性を維持します。
数値に対するモジュロ演算の実行に加えて % 演算子は文字列 (string) とユニコードオブジェクトにオーバーロードされ、文字列の書式化
(文字列の挿入としても知られる) を行います。文字列の書式化の構文は Python ライブラリリファレンス 文字列フォーマット操作 節を参照してください。
バージョン 2.3 で撤廃: 切り捨て除算演算子、モジュロ演算子、および divmod() 関数は、複素数に対してはもはや定義されていません。目的に合うならば、代わりに
abs() を使って浮動小数点に変換してください。
+ (加算) 演算は、引数を加算した値を返します。引数は双方とも数値型か、双方とも同じ型のシーケンスでなければなりません。前者の場合、数値は共通の型に変換され、加算されます。後者の場合、シーケンスは結合 (concatenate) されます。
- (減算) 演算は、引数間で減算を行った値を返します。数値引数はまず共通の型に変換されます。
シフト演算 (shifting operation)
シフト演算は、算術演算よりも低い優先順位を持っています:
shift_expr ::= a_expr | shift_expr ( "<<" | ">>" ) a_expr
シフトの演算子は整数または長整数を引数にとります。引数は共通の型に変換されます。シフト演算では、最初の引数を二つ目の引数に応じたビット数だけ、左または右にビットシフトします。
n ビットの右シフトは pow(2,n) による除算として定義されています。 n ビットの左シフトは pow(2,n)
による乗算として定義されます。負のビット数でシフトを行うと ValueError 例外を送出します。
ビット単位演算の二項演算 (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) をとった値になります。引数は整数または長整数でなければなりません。引数は共通の型に変換されます。
比較 (comparison)
C 言語と違って、Python における比較演算子は同じ優先順位をもっており、全ての算術演算子、シフト演算子、ビット単位演算子よりも低くなっています。また a < b < c が数学で伝統的に用いられているのと同じ解釈になる点も C 言語と違います:
comparison ::= or_expr ( comp_operator or_expr )*
comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "<>" | "!="
| "is" ["not"] | ["not"] "in"
比較演算の結果はブール値: True または False になります。
比較はいくらでも連鎖することができます。例えば x < y <= z は x < y and y <= z
と等価になります。ただしこの場合、前者では y はただ一度だけ評価される点が異なります (どちらの場合でも、 x < y が偽になると
z の値はまったく評価されません)。
形式的には、 a, b, c, ..., y, z が式で op1, op2, ..., opN が比較演算子である場合、 a op1 b op2 c ... y opN z は a op1 b and b op2 c and ... y opN z
と等価になります。ただし、前者では各式は多くても一度しか評価されません。
a op1 b op2 c と書いた場合、 a から c までの範囲にあるかどうかのテストを指すのではないことに注意してください。例えば x < y > z は (きれいな書き方ではありませんが) 完全に正しい文法です。
<> と != の二つの形式は等価です; C との整合性を持たせるためには != を推奨します; 以下で != について触れている部分では <> を使うこともできます。 <> のような書き方は、現在では古い書き方とみなされています。
演算子 <, >, ==, >=, <=, および != は、二つのオブジェクト間の値を比較します。オブジェクトは同じ型である必要はありません。双方のオブジェクトが数値であれば、共通型への変換が行われます。それ以外の場合、異なる型のオブジェクトは 常に 不等であるとみなされ、一貫してはいるが規定されていない方法で並べられます。組み込み型でないオブジェクト比較の振る舞いは __cmp__ メソッドや __gt__ といったリッチな比較メソッドを定義することでコントロールすることができます。これは 特殊メソッド名 セクションで説明されています。
(このような比較演算の変則的な定義は、ソートのような操作や in および not in といった演算子の定義を単純化するためのものです。将来、異なる型のオブジェクト間における比較規則は変更されるかもしれません。)
同じ型のオブジェクト間における比較は、型によって異なります:
数値間の比較では、算術的な比較が行われます。
文字列間の比較では、各文字に対する等価な数値型 (組み込み関数 ord() の結果) を使って辞書的な (lexicographically)
比較が行われます。Unicode および 8 ビット文字列は、この動作に関しては完全に互換です。
タプルやリスト間の比較では、対応する各要素の比較結果を使って辞書的な比較が行われます。このため、二つのシーケンスを等価にするためには、各要素が完全に等価でなくてはならず、シーケンスは同じ型で同じ長さをもっていなければなりません。
二つのシーケンスが等価でない場合、異なる値を持つ最初の要素間での比較に従った順序関係になります。例えば cmp([1,2,x], [1,2,y]) は
cmp(x,y) と等しい結果を返します。片方の要素に対応する要素が他方にない場合、より短いシーケンスが前に並びます
(例えば、 [1,2] < [1,2,3] となります)。
マップ (辞書) 間の比較では、(key, value) からなるリストをソートしたものが等しい場合に等価になります。
等価性評価以外の結果は一貫したやりかたで解決されるか、定義されないかのいずれかです。
その他のほとんどの組み込み型のオブジェクト比較では、同じオブジェクトでないかぎり等価にはなりません;あるオブジェクトの他のオブジェクトに対する大小関係は任意に決定され、一つのプログラムの実行中は一貫したものとなります。
演算子 in および not in は、コレクション型の要素であるかどうか (メンバシップ、membership)
を調べます。 x in s は、 x がコレクション型 s のメンバである場合には真となり、それ以外の場合には偽となります。 x not in s
は x in s の否定 (negation) を返します。コレクション型のメンバシップテストは、伝統的にはシーケンス型に限定されてきました;
すなわち、あるオブジェクトがコレクション型のメンバとなるのは、そのコレクション型がシーケンスであり、シーケンスがオブジェクトと等価な要素を含む場合でした。しかし、他の多くのオブジェクトのためにシーケンスでなくてもメンバシップテストをサポートしています。特に、辞書型では、(キーのための)メンバシップテストをサポートしています。
リストやタプル型について x in y は x == y[i] となるようなインデクス i
が存在するとき、かつそのときに限り真になります。
Unicode 文字列または文字列型については、 x in y は x が y の部分文字列であるとき、かつそのときに限り真になります。この演算と等価なテストは y.find(x) != -1 です。 x および y は同じ型である必要はないので注意してください。すなわち u'ab' in 'abc' は True を返すことになります。空文字列は、他のどんな文字列に対しても常に部分文字列とみなされます。従って "" in "abc" は True を返すことになります。
バージョン 2.3 で変更: 以前は、 x は長さ 1 の文字列型でなければなりませんでした.
__contains__() メソッドの定義されたユーザ定義クラスでは、 x in y が真となるのは
y.__contains__(x) が真となるとき、かつそのときに限ります。
__contains__() を定義していないが __iter__() は定義しているユーザ定義クラスでは、
x in y は x == z となるようなある値 z が y 内にわたる反復で生成された場合、
true となります。もし、反復の間に例外が発生すれば、 in が例外を発生させたようにみえます。
最終的には、旧式の反復プロトコルの実行を試みます、もし
__getitem__() を定義しているようなユーザ定義クラスでは、 x in y は
x == y[i] となるような非負の整数インデクス i が存在するとき、かつそのときにかぎり真となります。インデクス i が負である場合に IndexError 例外が送出されることはありません。
(別の何らかの例外が送出された場合、例外は in から送出されたかのようになります)。
演算子 not in は in の真値を反転した値として定義されています。
演算子 is および is not は、オブジェクトのアイデンティティに対するテストを行います:
x is y は、 x と y が同じオブジェクトを指すとき、かつそのときに限り真になります。 x is not y は is
の真値を反転したものになります。
ブール演算 (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
ブール演算のコンテキストや、式が制御フロー文中で使われる最には、以下の値: False 、 None 、すべての型における数値のゼロ、空の文字列とコンテナ (文字列、タプル、リスト、辞書、set、frozenset を含む) は偽 (false) であると解釈されます。それ以外の値は真 (true)
であると解釈されます。
(この振る舞いを変更する方法については特殊メソッド __nonzero__() を参照してください)
演算子 not は、引数が偽である場合には 1 を、それ以外の場合には 0 になります。
式 x and y は、まず x を評価します; x が偽なら x の値を返します; それ以外の場合には、 y
の値を評価し、その結果を返します。
式 x or y は、まず x を評価します; x が真なら x の値を返します; それ以外の場合には、 y
の値を評価し、その結果を返します。
(and も not も、返す値を 0 や 1 に制限するのではなく、最後に評価した引数の値を返すので注意してください。この仕様は、例えば s を文字列として s が空文字列の場合にデフォルトの値に置き換えるような場合に、 s or 'foo' と書くと期待通りの値になるために便利なことがあります。
not は、式の値でなく独自に値を作成して返すので、引数と同じ型の値を返すような処理に煩わされることはありません。例えば、 not
'foo' は、 '' ではなく 0 になります)
条件演算 (Conditional Expressions)
バージョン 2.5 で追加.
conditional_expression ::= or_test ["if" or_test "else" expression]
expression ::= conditional_expression | lambda_form
条件演算式 (しばしば、”三項演算子” と呼ばれます) は最も優先度が低いPython の操作です。
x if C else y という式は最初に条件 C (x では ありません) を評価します;
C が true の場合 x が評価され値が返されます; それ以外の場合には y が評価され返されます。
条件演算に関してより詳しくは PEP 308 を参照してください。
ラムダ (lambda)
lambda_form ::= "lambda" [parameter_list]: expression
old_lambda_form ::= "lambda" [parameter_list]: old_expression
ラムダ形式 (lambda form, ラムダ式 (lambda expression)) は、構文法的には式と同じ位置付けになります。ラムダは、無名関数を作成できる省略記法です; 式 lambda arguments: expression
は、関数オブジェクトになります。ラムダが表す無名オブジェクトは、以下のコード
def name(arguments):
return expression
で定義された関数と同様に動作します。
引数リストの構文法については 関数定義 節を参照してください。ラムダ形式で作成された関数は、実行文 (statement)
を含むことができないので注意してください。
式のリスト
expression_list ::= expression ( "," expression )* [","]
少なくとも一つのカンマを含む式のリストは、タプルになります。タプルの長さは、リスト中の式の数に等しくなります。リスト中の式は左から右へと順に評価されます。
単一要素のタプル (別名 単集合 (singleton) ) を作りたければ、末尾にカンマが必要です。単一の式だけで、末尾にカンマをつけない場合には、タプルではなくその式の値になります (空のタプルを作りたいなら、中身が空の丸括弧ペア: () を使います。)
評価順序
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
まとめ
以下の表は、Python における演算子を、優先順位 の最も低い (結合度が最も低い) ものから最も高い (結合度が最も高い) ものの順に並べたものです。同じボックス内に示された演算子は同じ優先順位を持ちます。演算子の文法が示されていないかぎり、演算子は全て二項演算子です。同じボックス内の演算子は、左から右へとグループ化されます (値のテストを含む比較演算子を除きます。比較演算子は、左から右に連鎖します —
比較 (comparison) を参照してください。また、べき乗演算子も除きます。べき乗演算子は右から左にグループ化されます)。
演算子 |
説明 |
lambda |
ラムダ式 |
if – else |
条件演算 |
or |
ブール演算 OR |
and |
ブール演算 AND |
not x |
ブール演算 NOT |
==
in, not in,
is, is not, <,
<=, >, >=, <>, !=, == |
メンバシップテスト、アイデンティティテストを含めた比較 |
| |
ビット単位 OR |
^ |
ビット単位 XOR |
& |
ビット単位 AND |
<<, >> |
シフト演算 |
+, - |
加算および減算 |
*, /, //, % |
乗算、除算、剰余 |
+x, -x, ~x |
正符号、負符号、ビット単位 NOT |
** |
べき乗 |
x[index], x[index:index],
x(arguments...), x.attribute |
添字指定、スライス操作属性参照 |
(expressions...),
[expressions...],
{key:datum...},
`expressions...` |
式結合またはタプル表現、リスト表現、辞書表現、文字列への型変換 |
注記