6. 式 (expression)¶
この章では、Python の式における個々の要素の意味について解説します。
構文上の注意: この章以降では、文法の表記法 を字句解析ではなく構文の記述に使います。
構文規則の (選択肢の 1 つの) 形式が次のように記述され、
name: othername
で記述されていて、この構文特有の意味付け (semantics) が記述されていない場合、 name の形式をとる構文の意味付けは othername の意味付けと同じになります。
6.1. 算術変換 (arithmetic conversion)¶
以下の算術演算子の説明で「数値の引数を共通の実数型に変換する」とある場合、組み込みの数値型に対する演算子の実装が、標準ライブラリのドキュメントの 数値型 の節で説明するとおりに動作することを意味します。
特定の演算子や数値以外のオペランド (例えば % 演算子の左オペランドとしての文字列) には、追加の規則が適用されます。
拡張では独自の変換動作を定義する必要があります。
6.2. アトム、原子的要素 (atom)¶
Atoms are the most basic elements of expressions. The simplest atoms are names or literals. Forms enclosed in parentheses, brackets or braces are also categorized syntactically as atoms.
形式的には、アトムの構文は次のとおりです。
atom: | 'True' | 'False' | 'None' | '...' |identifier|literal|enclosureenclosure: |parenth_form|list_display|dict_display|set_display|generator_expression|yield_atom
6.2.1. 組み込み定数¶
キーワード True、False、None は 組み込み定数 の名前です。
トークン ... は Ellipsis 定数を表します。
これらのアトムを評価すると、対応する値が得られます。
注釈
グローバル変数として利用できる組み込み定数はほかにもありますが、キーワード なのはここで挙げたものだけです。 特に、これらの名前には再代入できず、属性としても使えません。
>>> False = 123
File "<input>", line 1
False = 123
^^^^^
SyntaxError: cannot assign to False
6.2.2. 識別子 (identifier、または名前 (name))¶
アトムの形になっている識別子 (identifier) は名前 (name) です。字句定義については 名前 (識別子とキーワード) 節を、名前付けや束縛については 名前づけと束縛 (naming and binding) 節を参照してください。
名前があるオブジェクトに束縛されている場合、名前 atom を評価するとそのオブジェクトになります。名前が束縛されていない場合、 atom を評価しようとすると NameError 例外を送出します。
6.2.2.1. プライベート名のマングリング¶
クラス定義のテキスト内に現れる識別子が、2 個以上のアンダースコアで始まり、2 個以上のアンダースコアで終わらない場合、そのクラスの プライベート名 とみなされます。
参考
より正確には、プライベート名はコードを生成する前に、より長い形式に変換されます。 変換後の名前が 255 文字を超える場合は、実装で定めた方法で切り詰められることがあります。
変換は識別子を使う構文上の文脈によらず行われますが、マングリングの対象は次のプライベートな識別子だけです。
代入または読み取りを行う変数の名前と、アクセスする属性の名前。
ただし、入れ子の関数、クラス、型エイリアスの
__name__属性はマングリングされません。import __spamの__spamなど、インポートするモジュールの名前。 モジュールがパッケージの一部である場合 (名前にドットを含む場合) はマングリング されません。 例えばimport __foo.barの__fooはマングリングされません。from spam import __fの__fなど、インポートするメンバの名前。
変換規則は次のとおりです。
クラス名から先頭のアンダースコアを取り除き、先頭にアンダースコアを 1 個付けたものを、識別子の前に挿入します。 例えば
Foo、_Foo、__Fooという名前のクラス内の識別子__spamは、_Foo__spamに変換されます。クラス名がアンダースコアだけからなる場合、変換しても名前は変わりません。 例えば
_や__という名前のクラス内の識別子__spamはそのままです。
6.2.3. リテラル¶
リテラル は、値をテキストで表記したものです。 Python は数値、文字列、バイト列のリテラルをサポートします。 フォーマット済み文字列 と テンプレート文字列 も文字列リテラルとして扱います。
数値リテラルは、整数、浮動小数点数、虚数のいずれかを表す 1 個の NUMBER トークンからなります。
詳細は字句解析のドキュメントの 数値リテラル の節を参照してください。
文字列リテラルとバイト列リテラルは、複数のトークンからなる場合があります。 詳細は 文字列リテラルの結合 (concatenation) を参照してください。
-3 や 3+4.2j などの負数や複素数は、構文上はリテラルではなく、- または + 演算子を使う 単項 または 二項 の算術演算です。
リテラルを評価すると、指定された型 (int、float、complex、str、bytes、Template) と値を持つオブジェクトが得られます。
浮動小数点数リテラルと虚数リテラルでは、値が近似される場合があります。
リテラルの形式文法は次のとおりです。
literal:strings|NUMBER
6.2.3.1. リテラルとオブジェクトの同一性¶
リテラルは全て変更不能なデータ型に対応します。このため、オブジェクトのアイデンティティはオブジェクトの値ほど重要ではありません。同じ値を持つ複数のリテラルを評価した場合、(それらのリテラルがプログラムの同じ場所由来のものであっても、そうでなくても) 同じオブジェクトを指しているか、まったく同じ値を持つ別のオブジェクトになります。
CPython の実装の詳細
例えば CPython では、同じ値を持つ 小さい 整数を評価すると同じオブジェクトが得られます。
>>> x = 7
>>> y = 7
>>> x is y
True
一方、大きい整数を評価すると別々のオブジェクトが得られます。
>>> x = 123456789
>>> y = 123456789
>>> x is y
False
この動作は、将来の CPython バージョンで変わる可能性があります。 特に、「小さい」整数と「大きい」整数の境界は過去にも変わっています。
CPython は is を使ってリテラルを比較すると SyntaxWarning を出します。
>>> x = 7
>>> x is 7
<input>:1: SyntaxWarning: "is" with 'int' literal. Did you mean "=="?
True
詳細は いつ is 演算子での同一性テストが頼れますか? を参照してください。
テンプレート文字列 は不変ですが、Interpolation の値として可変なオブジェクトを参照することがあります。
この節では、2 つの t-string は構造と値の 同一性 の両方が一致する場合に「同じ値」を持つものとします。
現在は、テンプレート文字列を評価するたびに別のオブジェクトが生成されます。
6.2.3.2. 文字列リテラルの結合 (concatenation)¶
複数の文字列リテラルやバイト列リテラルを隣り合わせに書けます。 引用符の形式が異なっていても構いません。 意味はそれらを連結したものと同じです。
>>> "hello" 'world'
"helloworld"
この機能は構文のレベルで定義されているため、リテラルにしか使えません。 文字列の式を実行時に連結するには、'+' 演算子を使えます。
>>> greeting = "Hello"
>>> space = " "
>>> name = "Blaise"
>>> print(greeting + space + name) # print(greeting space name) とは書けない
Hello Blaise
リテラルの連結では、raw 文字列、三重クォート文字列、フォーマット済み文字列リテラルを自由に混在させられます。 例えば次のように書きます。
>>> "Hello" r', ' f"{name}!"
"Hello, Blaise!"
この機能を使うと、必要なバックスラッシュの数を減らしたり、長い文字列を複数の行に分割したり、文字列の一部ごとにコメントを付けたりできます。 例えば次のように書きます。
re.compile("[A-Za-z_]" # 英字またはアンダースコア
"[A-Za-z0-9_]*" # 英字、数字またはアンダースコア
)
ただし、バイト列リテラルと組み合わせられるのは他のバイト列リテラルだけで、どの種類の文字列リテラルとも組み合わせられません。 また、テンプレート文字列リテラルと組み合わせられるのは、他のテンプレート文字列リテラルだけです。
>>> t"Hello" t"{name}!"
Template(strings=('Hello', '!'), interpolations=(...))
形式的には次のように定義します。
strings: (STRING|fstring)+ |tstring+
6.2.4. Parenthesized forms¶
A parenthesized form is an optional expression list enclosed in parentheses:
parenth_form: "(" [starred_expression] ")"
A parenthesized expression list yields whatever that expression list yields: if the list contains at least one comma, it yields a tuple; otherwise, it yields the single expression that makes up the expression list.
An empty pair of parentheses yields an empty tuple object. Since tuples are immutable, the same rules as for literals apply (i.e., two occurrences of the empty tuple may or may not yield the same object).
Note that tuples are not formed by the parentheses, but rather by use of the comma. The exception is the empty tuple, for which parentheses are required --- allowing unparenthesized "nothing" in expressions would cause ambiguities and allow common typos to pass uncaught.
6.2.5. Displays for lists, sets and dictionaries¶
For constructing a list, a set or a dictionary Python provides special syntax called "displays", each of them in two flavors:
either the container contents are listed explicitly, or
they are computed via a set of looping and filtering instructions, called a comprehension.
Common syntax elements for comprehensions are:
comprehension:assignment_expressioncomp_forcomp_for: ["async"] "for"target_list"in"or_test[comp_iter] comp_iter:comp_for|comp_ifcomp_if: "if"or_test[comp_iter]
The comprehension consists of a single expression followed by at least one
for clause and zero or more for or if clauses.
In this case, the elements of the new container are those that would be produced
by considering each of the for or if clauses a block,
nesting from left to right, and evaluating the expression to produce an element
each time the innermost block is reached.
However, aside from the iterable expression in the leftmost for clause,
the comprehension is executed in a separate implicitly nested scope. This ensures
that names assigned to in the target list don't "leak" into the enclosing scope.
The iterable expression in the leftmost for clause is evaluated
directly in the enclosing scope and then passed as an argument to the implicitly
nested scope. Subsequent for clauses and any filter condition in the
leftmost for clause cannot be evaluated in the enclosing scope as
they may depend on the values obtained from the leftmost iterable. For example:
[x*y for x in range(10) for y in range(x, x+10)].
内包表記が常に適切な型のコンテナになるのを保証するために、 yield 式や yield from 式は暗黙的な入れ子のスコープでは禁止されています。
Since Python 3.6, in an async def function, an async for
clause may be used to iterate over a asynchronous iterator.
A comprehension in an async def function may consist of either a
for or async for clause following the leading
expression, may contain additional for or async for
clauses, and may also use await expressions.
If a comprehension contains async for clauses, or if it contains
await expressions or other asynchronous comprehensions anywhere except
the iterable expression in the leftmost for clause, it is called an
asynchronous comprehension. An asynchronous comprehension may suspend the
execution of the coroutine function in which it appears.
See also PEP 530.
Added in version 3.6: Asynchronous comprehensions were introduced.
バージョン 3.8 で変更: yield および yield from は暗黙的な入れ子のスコープでは禁止となりました。
バージョン 3.11 で変更: 非同期関数の内包表記の中でも、非同期内包表記を使えるようになりました。 外側の内包表記も暗黙的に非同期になります。
6.2.6. リスト表示¶
A list display is a possibly empty series of expressions enclosed in square brackets:
list_display: "[" [flexible_expression_list|comprehension] "]"
A list display yields a new list object, the contents being specified by either a list of expressions or a comprehension. When a comma-separated list of expressions is supplied, its elements are evaluated from left to right and placed into the list object in that order. When a comprehension is supplied, the list is constructed from the elements resulting from the comprehension.
6.2.7. 集合表示¶
A set display is denoted by curly braces and distinguishable from dictionary displays by the lack of colons separating keys and values:
set_display: "{" (flexible_expression_list|comprehension) "}"
A set display yields a new mutable set object, the contents being specified by either a sequence of expressions or a comprehension. When a comma-separated list of expressions is supplied, its elements are evaluated from left to right and added to the set object. When a comprehension is supplied, the set is constructed from the elements resulting from the comprehension.
An empty set cannot be constructed with {}; this literal constructs an empty
dictionary.
6.2.8. 辞書表示¶
A dictionary display is a possibly empty series of dict items (key/value pairs) enclosed in curly braces:
dict_display: "{" [dict_item_list|dict_comprehension] "}" dict_item_list:dict_item(","dict_item)* [","] dict_item:expression":"expression| "**"or_exprdict_comprehension:expression":"expressioncomp_for
A dictionary display yields a new dictionary object.
If a comma-separated sequence of dict items is given, they are evaluated from left to right to define the entries of the dictionary: each key object is used as a key into the dictionary to store the corresponding value. This means that you can specify the same key multiple times in the dict item list, and the final dictionary's value for that key will be the last one given.
A double asterisk ** denotes dictionary unpacking.
Its operand must be a mapping. Each mapping item is added
to the new dictionary. Later values replace values already set by
earlier dict items and earlier dictionary unpackings.
Added in version 3.5: 辞書表示のアンパックは最初に PEP 448 で提案されました。
A dict comprehension, in contrast to list and set comprehensions, needs two expressions separated with a colon followed by the usual "for" and "if" clauses. When the comprehension is run, the resulting key and value elements are inserted in the new dictionary in the order they are produced.
Restrictions on the types of the key values are listed earlier in section 標準型の階層. (To summarize, the key type should be hashable, which excludes all mutable objects.) Clashes between duplicate keys are not detected; the last value (textually rightmost in the display) stored for a given key value prevails.
バージョン 3.8 で変更: Python 3.8 より前のバージョンでは、辞書内包表記において、キーと値の評価順序は明示されていませんでした。CPython では、値がキーより先に評価されていました。バージョン 3.8 からは PEP 572 で提案されているように、キーが値より先に評価されます。
6.2.9. ジェネレータ式¶
ジェネレータ式 の構文は、角括弧ではなく丸括弧で囲むことを除いて、リスト 内包表記 と同じです。 例えば次のように書きます。
>>> iterator = (x ** 2 for x in range(10))
>>> iterator
<generator object <genexpr> at ...>
実行時にジェネレータ式を評価すると、対応するリスト内包表記と同じ値を yield する generator iterator が得られます。
>>> list(iterator)
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
従って、上の例はおおよそ次のジェネレータ関数を定義して呼び出すことに相当します。
def make_generator_of_squares(iterator):
for x in iterator:
yield x ** 2
make_generator_of_squares(iter(range(10)))
呼び出しにおいて、ジェネレータ式が唯一の位置引数で、キーワード引数もない場合は、外側の丸括弧を省略できます。 詳細は 呼び出しの節 を参照してください。 例えば次のように書きます。
# `sum` の後の丸括弧は呼び出しの構文の一部:
>>> sum(x ** 2 for x in range(10))
285
# 引数がほかにもある場合はジェネレータ自体の丸括弧が必要:
>>> sum((x ** 2 for x in range(10)), start=1000)
1285
一番左の for 節のイテラブルを表す式は、即座に評価されます。
そのため、この式が送出するエラーは、最初の値を取得するときではなく、ジェネレータ式を定義した時点で発生します。
>>> (x ** 2 for x in nonexistent_iterable)
Traceback (most recent call last):
...
NameError: name 'nonexistent_iterable' is not defined
式を評価した後は、その結果に iter() を呼び出したかのようにイテレータを作成します。
イテレータの作成中に送出されるエラーも即座に発生します。
>>> (x ** 2 for x in None)
Traceback (most recent call last):
...
TypeError: 'NoneType' object is not iterable
その他の式はすべて、通常のジェネレータと同じように遅延評価されます (イテレータに値を yield するよう要求したときに評価します)。
>>> iterator = (nonexistent_value for x in range(10))
>>> iterator
<generator object <genexpr> at ...>
>>> list(iterator)
Traceback (most recent call last):
...
NameError: name 'nonexistent_value' is not defined
>>> iterator = (x * y for x in range(10) for y in nonexistent_iterable)
>>> iterator
<generator object <genexpr> at ...>
>>> list(iterator)
Traceback (most recent call last):
...
NameError: name 'nonexistent_iterable' is not defined
ジェネレータ式自体の期待される動作を妨げないように、暗黙的に入れ子になったスコープ内では yield 式と yield from 式は禁止されています。
async for 節または await 式を含むジェネレータ式は、非同期ジェネレータ式 と呼ばれます。
非同期ジェネレータ式は、新しい非同期ジェネレータオブジェクトを返します。
これは非同期イテレータです (非同期イテレータ (Asynchronous Iterator) を参照してください)。
ジェネレータ式の形式文法は次のとおりです。
generator_expression: "("expressioncomp_for")"
Added in version 3.6: 非同期ジェネレータ式が導入されました。
バージョン 3.7 で変更: Python 3.7 より前では、非同期ジェネレータ式は async def コルーチンでしか使えませんでした。
3.7 からは、任意の関数で非同期ジェネレータ式が使えるようになりました。
バージョン 3.8 で変更: yield および yield from は暗黙的な入れ子のスコープでは禁止となりました。
6.2.10. Yield 式¶
yield_atom: "("yield_expression")" yield_from: "yield" "from"expressionyield_expression: "yield"yield_list|yield_from
yield 式は ジェネレータ 関数や 非同期ジェネレータ 関数を定義するときに使われます。従って、関数定義の本体でのみ使えます。
関数の本体で yield 式 を使用するとその関数はジェネレータ関数になり、 async def 関数の本体で使用するとそのコルーチン関数は非同期ジェネレータ関数になります。
例えば次のようになります:
def gen(): # ジェネレータ関数を定義
yield 123
async def agen(): # 非同期ジェネレータ関数を定義
yield 123
内包表記やジェネレータ式を実装するために暗黙的に定義されるスコープ内では、yield 式を使えません。
これは、それを含むスコープに副作用を及ぼすためです。
バージョン 3.8 で変更: yield 式は、暗黙的な入れ子のスコープで内包表記やジェネレータ式を実装するための使用が禁止になりました。
ジェネレータ関数についてはすぐ下で説明されています。非同期ジェネレータ関数は、 非同期ジェネレータ関数 (asynchronous generator function) 節に分けて説明されています。
ジェネレータ関数を呼び出すと、ジェネレータと呼ばれるイテレータを返します。
このジェネレータが、その後のジェネレータ関数の実行を制御します。
ジェネレータのメソッドのいずれかを呼ぶと実行が始まり、最初の yield 式まで進んで再び一時停止します。
このとき yield_list の値をジェネレータの呼び出し元に返します。
yield_list が省略されていれば None を返します。
一時停止とは、ローカル変数の現在の束縛、命令ポインタ、内部の評価スタック、例外処理の状態を含む、すべてのローカルな状態を保持することを意味します。
ジェネレータのメソッドを呼んで実行を再開すると、yield 式が通常の外部呼び出しであったかのように関数を続行できます。
再開後の yield 式の値は、実行を再開させたメソッドによって決まります。
__next__() を使った場合 (通常は for や組み込み関数 next() を通じて使います) は None になります。
send() を使った場合は、そのメソッドに渡した値になります。
このように、ジェネレータ関数はコルーチンとよく似ています。 何度も yield し、複数のエントリポイントを持ち、実行を一時停止できます。 唯一の違いは、ジェネレータ関数は yield した後にどこで実行を続けるかを制御できないことです。 制御は常にジェネレータの呼び出し元へ移ります。
yield 式は try 構造内で使用できます。ジェネレータの (参照カウントがゼロに達するか、ガベージコレクションによる) 完了前に再開されない場合、ジェネレータ-イテレータの close() メソッドが呼ばれ、finally 節が実行されます。
yield from <expr> を使用した場合、与えられた式はイテラブルでなければなりません。そのイテラブルをイテレートすることで生成された値は現在のジェネレータのメソッドの呼び出し元へ直接渡されます。send() で渡されたあらゆる値と throw() で渡されたあらゆる例外は根底のイテレータに適切なメソッドがあれば渡されます。適切なメソッドがない場合、send() は AttributeError か TypeError を、throw() は渡された例外を即座に送出します。
根底のイテレータの完了時、引き起こされた StopIteration インスタンスの value 属性はその yield 式の値となります。
StopIteration を起こす際に明示的にセットされるか、サブイテレータがジェネレータであれば (サブイテレータからかえる値で) 自動的にセットされるかのどちらかです。
バージョン 3.3 で変更: サブイテレータに制御フローを委譲するために yield from <expr> が追加されました。
yield 式が代入文の単独の右辺式であるとき、括弧は省略できます。
参考
6.2.10.1. Generator-iterator methods¶
This subsection describes the methods of a generator iterator. They can be used to control the execution of a generator function.
Note that calling any of the generator methods below when the generator
is already executing raises a ValueError exception.
- generator.__next__()¶
Starts the execution of a generator function or resumes it at the last executed yield expression. When a generator function is resumed with a
__next__()method, the current yield expression always evaluates toNone. The execution then continues to the next yield expression, where the generator is suspended again, and the value of theyield_listis returned to__next__()'s caller. If the generator exits without yielding another value, aStopIterationexception is raised.This method is normally called implicitly, e.g. by a
forloop, or by the built-innext()function.
- generator.send(value)¶
Resumes the execution and "sends" a value into the generator function. The value argument becomes the result of the current yield expression. The
send()method returns the next value yielded by the generator, or raisesStopIterationif the generator exits without yielding another value. Whensend()is called to start the generator, it must be called withNoneas the argument, because there is no yield expression that could receive the value.
- generator.throw(value)¶
- generator.throw(type[, value[, traceback]])
Raises an exception at the point where the generator was paused, and returns the next value yielded by the generator function. If the generator exits without yielding another value, a
StopIterationexception is raised. If the generator function does not catch the passed-in exception, or raises a different exception, then that exception propagates to the caller.In typical use, this is called with a single exception instance similar to the way the
raisekeyword is used.For backwards compatibility, however, the second signature is supported, following a convention from older versions of Python. The type argument should be an exception class, and value should be an exception instance. If the value is not provided, the type constructor is called to get an instance. If traceback is provided, it is set on the exception, otherwise any existing
__traceback__attribute stored in value may be cleared.バージョン 3.12 で変更: The second signature (type[, value[, traceback]]) is deprecated and may be removed in a future version of Python.
- generator.close()¶
Raises a
GeneratorExitexception at the point where the generator function was paused (equivalent to callingthrow(GeneratorExit)). The exception is raised by the yield expression where the generator was paused. If the generator function catches the exception and returns a value, this value is returned fromclose(). If the generator function is already closed, or raisesGeneratorExit(by not catching the exception),close()returnsNone. If the generator yields a value, aRuntimeErroris raised. If the generator raises any other exception, it is propagated to the caller. If the generator has already exited due to an exception or normal exit,close()returnsNoneand has no other effect.バージョン 3.13 で変更: If a generator returns a value upon being closed, the value is returned by
close().
6.2.10.2. 使用例¶
以下の簡単なサンプルはジェネレータとジェネレータ関数の振る舞いを実際に紹介します:
>>> def echo(value=None):
... print("Execution starts when 'next()' is called for the first time.")
... try:
... while True:
... try:
... value = (yield value)
... except Exception as e:
... value = e
... finally:
... print("Don't forget to clean up when 'close()' is called.")
...
>>> generator = echo(1)
>>> print(next(generator))
Execution starts when 'next()' is called for the first time.
1
>>> print(next(generator))
None
>>> print(generator.send(2))
2
>>> generator.throw(TypeError, "spam")
TypeError('spam',)
>>> generator.close()
Don't forget to clean up when 'close()' is called.
yield from の使用例は、"What's New in Python." の PEP 380: サブジェネレータへの委譲構文 を参照してください。
6.2.10.3. 非同期ジェネレータ関数 (asynchronous generator function)¶
async def を使用して定義された関数やメソッドに yield 式があると、その関数は 非同期ジェネレータ 関数として定義されます。
非同期ジェネレータ関数が呼び出されると、非同期ジェネレータオブジェクトと呼ばれる非同期イテレータが返されます。
そして、そのオブジェクトはジェネレータ関数の実行を制御します。
通常、非同期ジェネレータオブジェクトは、コルーチン関数内の async for 文で使われ、これはジェネレータオブジェクトが for 文で使われる様子に類似します。
非同期ジェネレータのメソッドのいずれかを呼ぶと awaitable オブジェクトを返し、このオブジェクトを await すると実行が始まります。
最初の yield 式まで進んで再び一時停止し、yield_list の値を、await しているコルーチンに返します。
ジェネレータと同様、一時停止中はローカル変数の現在の束縛、命令ポインタ、内部の評価スタック、例外処理の状態を含む、すべてのローカルな状態を保持します。
非同期ジェネレータのメソッドが次に返すオブジェクトを await して実行を再開すると、yield 式が通常の外部呼び出しであったかのように関数を続行できます。
再開後の yield 式の値は、実行を再開させたメソッドによって決まります。
__anext__() を使った場合は None になります。
asend() を使った場合は、そのメソッドに渡した値になります。
break、呼び出し元のタスクのキャンセル、その他の例外によって非同期ジェネレータの処理を途中で終了すると、
ジェネレータの非同期の後始末コードが予期しない文脈で実行され、例外を送出したりコンテキスト変数にアクセスしたりする場合があります。
例えば、依存するタスクの存続期間が終わった後や、イベントループの終了時に非同期ジェネレータのガベージコレクションフックが呼ばれたときに実行される可能性があります。
これを防ぐため、呼び出し元は aclose() メソッドで非同期ジェネレータを明示的に閉じ、終了処理を行って、最終的にイベントループから切り離す必要があります。
非同期ジェネレータ関数では、try 構造内のどこでも yield 式を使えます。
ただし、非同期ジェネレータが再開されないまま終了処理を迎えた場合 (参照カウントが 0 に達した場合やガベージコレクションされた場合)、
try 構造内の yield 式による一時停止のため、実行待ちの finally 節が実行されない可能性があります。
この場合、非同期ジェネレータを実行するイベントループやスケジューラが、
非同期ジェネレータイテレータの aclose() メソッドを呼び、返されたコルーチンオブジェクトを実行して、実行待ちの finally 節が実行されるようにする責任を持ちます。
To take care of finalization upon event loop termination, an event loop should
define a finalizer function which takes an asynchronous generator-iterator and
presumably calls aclose() and executes the coroutine.
This finalizer may be registered by calling sys.set_asyncgen_hooks().
When first iterated over, an asynchronous generator-iterator will store the
registered finalizer to be called upon finalization. For a reference example
of a finalizer method see the implementation of
asyncio.Loop.shutdown_asyncgens in Lib/asyncio/base_events.py.
yield from <expr> 式は、非同期ジェネレータ関数で使われると文法エラーになります。
6.2.10.4. Asynchronous generator-iterator methods¶
This subsection describes the methods of an asynchronous generator iterator, which are used to control the execution of a generator function.
- async agen.__anext__()¶
Returns an awaitable which when run starts to execute the asynchronous generator or resumes it at the last executed yield expression. When an asynchronous generator function is resumed with an
__anext__()method, the current yield expression always evaluates toNonein the returned awaitable, which when run will continue to the next yield expression. The value of theyield_listof the yield expression is the value of theStopIterationexception raised by the completing coroutine. If the asynchronous generator exits without yielding another value, the awaitable instead raises aStopAsyncIterationexception, signalling that the asynchronous iteration has completed.This method is normally called implicitly by a
async forloop.
- async agen.asend(value)¶
Returns an awaitable which when run resumes the execution of the asynchronous generator. As with the
send()method for a generator, this "sends" a value into the asynchronous generator function, and the value argument becomes the result of the current yield expression. The awaitable returned by theasend()method will return the next value yielded by the generator as the value of the raisedStopIteration, or raisesStopAsyncIterationif the asynchronous generator exits without yielding another value. Whenasend()is called to start the asynchronous generator, it must be called withNoneas the argument, because there is no yield expression that could receive the value.
- async agen.athrow(value)¶
- async agen.athrow(type[, value[, traceback]])
Returns an awaitable that raises an exception of type
typeat the point where the asynchronous generator was paused, and returns the next value yielded by the generator function as the value of the raisedStopIterationexception. If the asynchronous generator exits without yielding another value, aStopAsyncIterationexception is raised by the awaitable. If the generator function does not catch the passed-in exception, or raises a different exception, then when the awaitable is run that exception propagates to the caller of the awaitable.バージョン 3.12 で変更: The second signature (type[, value[, traceback]]) is deprecated and may be removed in a future version of Python.
- async agen.aclose()¶
Returns an awaitable that when run will throw a
GeneratorExitinto the asynchronous generator function at the point where it was paused. If the asynchronous generator function then exits gracefully, is already closed, or raisesGeneratorExit(by not catching the exception), then the returned awaitable will raise aStopIterationexception. Any further awaitables returned by subsequent calls to the asynchronous generator will raise aStopAsyncIterationexception. If the asynchronous generator yields a value, aRuntimeErroris raised by the awaitable. If the asynchronous generator raises any other exception, it is propagated to the caller of the awaitable. If the asynchronous generator has already exited due to an exception or normal exit, then further calls toaclose()will return an awaitable that does nothing.
6.3. プライマリ¶
プライマリは、言語において最も結合の強い操作を表します。文法は以下のようになります:
primary:atom|attributeref|subscription|call
6.3.1. 属性参照¶
属性参照は、プライマリの後ろにピリオドと名前を連ねたものです:
attributeref:primary"."identifier
プライマリの評価結果は、属性参照をサポートする型のオブジェクトでなければなりません。 ほとんどのオブジェクトはこれをサポートします。 次に、このオブジェクトに対して、識別子を名前とする属性を取得するよう求めます。 得られる型と値はオブジェクトによって決まります。 同じ属性参照を複数回評価しても、別のオブジェクトが得られる場合があります。
この取得動作は、__getattribute__() メソッドや __getattr__() メソッドをオーバーライドしてカスタマイズできます。
最初に __getattribute__() メソッドが呼ばれ、値を返すか、属性がなければ AttributeError を送出します。
AttributeError が送出され、そのオブジェクトが __getattr__() メソッドを持っていれば、代わりにそのメソッドが呼ばれます。
6.3.2. 添字表記とスライス表記¶
添字表記 の構文は、通常 コンテナ の要素を選ぶために使います。
例えば dict から値を取得するのに使えます。
>>> digits_by_name = {'one': 1, 'two': 2}
>>> digits_by_name['two'] # キー 'two' を添字にして辞書にアクセス
2
添字表記では、添字を付けるオブジェクトである プライマリ の後に、角括弧で囲んだ 添字 を置きます。 最も単純な場合、添字は 1 個の式です。
添字を付けるオブジェクトの型に応じて、添字は キー (マッピング)、インデックス (シーケンス)、型引数 (ジェネリック型) とも呼ばれます。 構文上はどれも同じです。
>>> colors = ['red', 'blue', 'green', 'black']
>>> colors[3] # インデックス 3 を添字にしてリストにアクセス
'black'
>>> list[str] # 型引数 str でリスト型をパラメータ化
list[str]
実行時にインタープリタはプライマリと添字を評価し、添字を引数としてプライマリの __getitem__() または __class_getitem__() 特殊メソッド を呼び出します。
どちらのメソッドが呼ばれるかの詳細は __class_getitem__ と __getitem__ の違い を参照してください。
添字表記の動作を示すため、__getitem__() を実装して添字の値を表示する独自のオブジェクトを定義できます。
>>> class SubscriptionDemo:
... def __getitem__(self, key):
... print(f'subscripted with: {key!r}')
...
>>> demo = SubscriptionDemo()
>>> demo[1]
subscripted with: 1
>>> demo['a' * 3]
subscripted with: 'aaa'
組み込み型が添字表記をどう処理するかについては、__getitem__() のドキュメントを参照してください。
添字表記は、代入文 や 削除文 のターゲットにも使えます。
この場合、インタープリタは __getitem__() の代わりに、添字を付けたオブジェクトの __setitem__() または __delitem__() 特殊メソッド をそれぞれ呼び出します。
>>> colors = ['red', 'blue', 'green', 'black']
>>> colors[3] = 'white' # 指定したインデックスの項目を設定
>>> colors
['red', 'blue', 'green', 'white']
>>> del colors[3] # インデックス 3 の項目を削除
>>> colors
['red', 'blue', 'green']
以降の節で説明する高度な 添字 の形式は、すべて代入や削除にも使えます。
6.3.2.1. スライス表記 (slicing)¶
添字表記のより高度な形式である スライス表記 は、通常 シーケンス の一部分を取り出すために使います。 この形式の添字は、最大 3 個の式をコロンで区切った スライス です。 どの式も省略できますが、コロンは少なくとも 1 個必要です。
>>> number_names = ['zero', 'one', 'two', 'three', 'four', 'five']
>>> number_names[1:3]
['one', 'two']
>>> number_names[1:]
['one', 'two', 'three', 'four', 'five']
>>> number_names[:3]
['zero', 'one', 'two']
>>> number_names[:]
['zero', 'one', 'two', 'three', 'four', 'five']
>>> number_names[::2]
['zero', 'two', 'four']
>>> number_names[:-3]
['zero', 'one', 'two']
>>> del number_names[4:]
>>> number_names
['zero', 'one', 'two', 'three']
スライスを評価すると、インタープリタはコロンで区切った式の結果をそれぞれ start、stop、step 属性に持つ slice オブジェクトを構築します。
省略された式の評価結果は None です。
この slice オブジェクトは、前述のとおり __getitem__() または __class_getitem__() 特殊メソッド に渡されます。
# 上で定義した SubscriptionDemo インスタンスを引き続き使う:
>>> demo[2:3]
subscripted with: slice(2, 3, None)
>>> demo[::'spam']
subscripted with: slice(None, None, 'spam')
6.3.2.2. カンマ区切りの添字¶
添字には、カンマで区切った 2 個以上の式やスライスも指定できます。
# 上で定義した SubscriptionDemo インスタンスを引き続き使う:
>>> demo[1, 2, 3]
subscripted with: (1, 2, 3)
>>> demo[1:2, 3]
subscripted with: (slice(1, 2, None), 3)
この形式は、数値計算ライブラリで多次元データをスライスするためによく使われます。
この場合、インタープリタは式やスライスの結果から tuple を構築し、
前述のとおり __getitem__() または __class_getitem__() 特殊メソッド に渡します。
1 個の式やスライスの後にカンマを付けることで、要素が 1 個のタプルを添字として指定することもできます。
>>> demo['spam',]
subscripted with: ('spam',)
6.3.2.3. アスタリスク付きの添字表記¶
Added in version 3.11: tuple_slices の式にアスタリスクを付けられるようになりました。 PEP 646 を参照してください。
添字にはアスタリスク付きの式も含められます。
この場合、インタープリタはその結果をアンパックしてタプルにし、__getitem__() または __class_getitem__() に渡します。
# 上で定義した SubscriptionDemo インスタンスを引き続き使う:
>>> demo[*range(10)]
subscripted with: (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
アスタリスク付きの式は、カンマで区切った式やスライスと組み合わせられます。
>>> demo['a', 'b', *range(3), 'c']
subscripted with: ('a', 'b', 0, 1, 2, 'c')
6.3.2.4. 添字表記の形式文法¶
subscription:primary'['subscript']' subscript:single_subscript|tuple_subscriptsingle_subscript:proper_slice|assignment_expressionproper_slice: [expression] ":" [expression] [ ":" [expression] ] tuple_subscript: ','.(single_subscript|starred_expression)+ [',']
| 演算子は 順序付き選択を表す ことを思い出してください。
特に subscript で両方の選択肢が一致する場合は、最初の選択肢 (single_subscript) を優先します。
6.3.3. 呼び出し (call)¶
呼び出しは、呼び出し可能オブジェクト (例えば function) を arguments の系列とともに呼び出します。系列は空の系列であってもかまいません:
call:primary"(" [argument_list[","] |comprehension] ")" argument_list:positional_arguments[","starred_and_keywords] [","keywords_arguments] |starred_and_keywords[","keywords_arguments] |keywords_argumentspositional_arguments:positional_item(","positional_item)* positional_item:assignment_expression| "*"expressionstarred_and_keywords: ("*"expression|keyword_item) ("," "*"expression| ","keyword_item)* keywords_arguments: (keyword_item| "**"expression) (","keyword_item| "," "**"expression)* keyword_item:identifier"="expression
最後の位置引数やキーワード引数の後にカンマをつけてもかまいません。構文の意味付けに影響を及ぼすことはありません。
プライマリの評価結果は、呼び出し可能オブジェクトでなければなりません。
ユーザー定義関数、組み込み関数、組み込みオブジェクトのメソッド、クラスオブジェクト、クラスインスタンスのメソッド、
__call__() メソッドを持つすべてのオブジェクトは呼び出し可能です。
すべての引数の式は、呼び出しを試みる前に評価されます。
仮引数 (parameter) リストの構文は 関数定義 を参照してください。
キーワード引数がある場合は、まず次のように位置引数に変換します。
最初に、仮引数に対応する空のスロットのリストを作成します。
位置引数が N 個あれば、先頭の N 個のスロットに配置します。
次に各キーワード引数について、識別子から対応するスロットを決めます (識別子が最初の仮引数名と同じなら最初のスロットを使う、といった具合です)。
そのスロットがすでに埋まっていれば TypeError 例外を送出します。
そうでなければ、引数をそのスロットに入れます (式が None でもスロットは埋まります)。
すべての引数を処理した後、まだ空のスロットを関数定義の対応するデフォルト値で埋めます。
(デフォルト値は関数の定義時に一度だけ計算されます。
そのため、リストや辞書などの可変オブジェクトをデフォルト値にすると、対応する引数の値を指定しないすべての呼び出しが同じオブジェクトを共有します。
通常は避けるべきです。)
デフォルト値も指定されていない空のスロットが残れば、TypeError 例外を送出します。
そうでなければ、値を入れたスロットのリストを呼び出しの引数リストとして使います。
実装によっては、位置引数の仮引数に名前がない組み込み関数を提供する場合があります。
ドキュメントのために「名前を付けて」いても、キーワードでは指定できません。
CPython では、引数の解析に PyArg_ParseTuple() を使う C 実装の関数がこれに当たります。
仮引数スロットの数よりも多くの位置引数がある場合、構文 *identifier を使って指定された仮引数がないかぎり、 TypeError 例外が送出されます; 仮引数 *identifier がある場合、この仮引数は余分な位置引数が入ったタプル (もしくは、余分な位置引数がない場合には空のタプル) を受け取ります。
キーワード引数のいずれかが仮引数名に対応しない場合、構文 **identifier を使って指定された仮引数がない限り、 TypeError 例外が送出されます; 仮引数 **identifier がある場合、この仮引数は余分なキーワード引数が入った (キーワードをキーとし、引数値をキーに対応する値とした) 辞書を受け取ります。余分なキーワード引数がない場合には、空の (新たな) 辞書を受け取ります。
関数呼び出しに *expression という構文が現れる場合は、 expression の評価結果は イテラブル でなければなりません。
そのイテラブルの要素は、追加の位置引数であるかのように扱われます。
f(x1, x2, *y, x3, x4) という呼び出しにおいて、 y の評価結果がシーケンス y1, ..., yM だった場合は、この呼び出しは M+4 個の位置引数 x1, x2, y1, ..., yM, x3, x4 での呼び出しと同じになります。
この結論としては、 *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 の評価結果は マッピング でなければなりません。その内容は追加のキーワード引数として扱われます。
キーにマッチする引数が (明示的なキーワード引数によって、あるいは他のアンパックの中で) 既に値を与えられていたなら、 TypeError 例外が送出されます。
**expression を使う場合、マッピングのキーはすべて文字列でなければなりません。
各値は、キーワードで値を指定でき、名前がキーと等しい最初の仮引数に代入されます。
キーが Python の識別子である必要はありません (例えば "max-temp °F" も使えますが、宣言可能な仮引数とは一致しません)。
一致する仮引数がなければ、** の仮引数がある場合はそこにキーと値のペアが集められ、ない場合は TypeError 例外を送出します。
*identifier や **identifier 構文を使った仮引数は、位置引数スロットやキーワード引数名にすることができません。
バージョン 3.5 で変更: 関数呼び出しは任意の数の * アンパックと ** アンパックを受け取り、位置引数はイテラブルアンパック (*) の後ろに置け、キーワード引数は辞書アンパック (**) の後ろに置けるようになりました。
最初に PEP 448 で提案されました。
呼び出しを行うと、例外を送出しない限り、常に何らかの値を返します。 None を返す場合もあります。戻り値がどのように算出されるかは、呼び出し可能オブジェクトの形態によって異なります。
各形態では---
- ユーザ定義関数:
引数リストを渡して、関数のコードブロックを実行します。 コードブロックは最初に、渡された引数を仮引数に束縛します。 この処理は 関数定義 で説明しています。 コードブロック内で
return文を実行すると、それが関数呼び出しの戻り値を指定します。return文を実行せずにコードブロックの末尾に達した場合、戻り値はNoneです。- 組み込み関数またはメソッド:
結果はインタプリタに依存します; 組み込み関数やメソッドの詳細は 組み込み関数 を参照してください。
- クラスオブジェクト:
そのクラスの新しいインスタンスが返されます。
- クラスインスタンスメソッド:
対応するユーザ定義の関数が呼び出されます。このとき、呼び出し時の引数リストより一つ長い引数リストで呼び出されます: インスタンスが引数リストの先頭に追加されます。
- クラスインスタンス:
クラスは
__call__()メソッドを定義していなければなりません。 そのメソッドを呼び出したのと同じ動作になります。
6.4. Await 式¶
awaitable オブジェクトでの coroutine 実行を一時停止します。 coroutine function 内でのみ使用できます。
await_expr: "await" primary
Added in version 3.5.
6.5. べき乗演算 (power operator)¶
べき乗演算は、左側にある単項演算子よりも強い結合優先順位となります。一方、右側にある単項演算子よりは弱い結合優先順位になっています。構文は以下のようになります:
power: (await_expr|primary) ["**"u_expr]
従って、べき乗演算子と単項演算子の並びを丸括弧で囲まなければ、演算子は右から左へ評価されます (これはオペランドの評価順序を制限するものではありません)。
-1**2 の結果は -1 です。
べき乗演算子は、引数を 2 個渡した組み込み関数 pow() と同じ意味を持ちます。
左の引数を右の引数でべき乗した値を返します。
数値の引数は最初に 共通の型に変換 され、結果もその型になります。
整数の被演算子では、第二引数が負でない限り、結果は被演算子と同じ型になります; 第二引数が負の場合、全ての引数は浮動小数点型に変換され、浮動小数点型が返されます。例えば 10**2 は 100 を返しますが、10**-2 は 0.01 を返します。
0.0 を負の数でべき乗すると ZeroDivisionError を送出します。負の数を小数でべき乗した結果は複素数 (complex number) になります。 (以前のバージョンでは ValueError を送出していました)
この演算は、特殊メソッド __pow__() と __rpow__() でカスタマイズできます。
6.6. 単項算術演算とビット単位演算 (unary arithmetic and bitwise operation)¶
全ての単項算術演算とビット単位演算は、同じ優先順位を持っています:
u_expr:power| "-"u_expr| "+"u_expr| "~"u_expr
単項の - (マイナス) 演算子は、数値の引数の符号を反転した値を返します。
この演算は特殊メソッド __neg__() でオーバーライドできます。
単項の + (プラス) 演算子は、数値の引数をそのまま返します。
この演算は特殊メソッド __pos__() でオーバーライドできます。
単項の ~ (反転) 演算子は、整数の引数をビット単位で反転した値を返します。
x のビット単位の反転は -(x+1) と定義されます。
整数、または特殊メソッド __invert__() をオーバーライドした独自のオブジェクトだけに適用できます。
上記の三つはいずれも、引数が正しい型でない場合には TypeError 例外が送出されます。
6.7. 二項算術演算 (binary arithmetic operation)¶
二項算術演算は、慣習的な優先順位を踏襲しています。演算子のいずれかは、特定の非数値型にも適用されるので注意してください。べき乗 (power) 演算子を除き、演算子には二つのレベル、すなわち乗算的 (multiplicatie) 演算子と加算的 (additie) 演算子しかありません:
m_expr:u_expr|m_expr"*"u_expr|m_expr"@"m_expr|m_expr"//"u_expr|m_expr"/"u_expr|m_expr"%"u_expra_expr:m_expr|a_expr"+"m_expr|a_expr"-"m_expr
* (乗算) 演算子は引数の積を返します。
引数は両方とも数値か、一方が整数でもう一方がシーケンスでなければなりません。
前者では、数値を 共通の実数型に変換 してから掛け合わせます。
後者では、シーケンスを繰り返します。
繰り返し回数が負なら空のシーケンスになります。
この演算は、特殊メソッド __mul__() と __rmul__() でカスタマイズできます。
バージョン 3.14 で変更: 片方のオペランドだけが複素数の場合、もう一方のオペランドは浮動小数点数に変換されます。
@ (at) 演算子は行列の乗算に対し使用されます。
Python の組み込み型はこの演算子を実装していません。
この演算は、特殊メソッド __matmul__() と __rmatmul__() でカスタマイズできます。
Added in version 3.5.
/ (除算) 演算子と // (切り捨て除算) 演算子は、引数の商を返します。
数値の引数は最初に 共通の型に変換 されます。
整数どうしの除算は浮動小数点数になり、整数どうしの切り捨て除算は整数になります。
切り捨て除算の結果は、数学的な除算の結果に床関数 (floor) を適用したものです。
0 による除算は ZeroDivisionError 例外を送出します。
除算は特殊メソッド __truediv__() と __rtruediv__() でカスタマイズできます。
切り捨て除算は特殊メソッド __floordiv__() と __rfloordiv__() でカスタマイズできます。
% (剰余) 演算子は、第 1 引数を第 2 引数で割った余りを返します。
数値の引数は最初に 共通の型に変換 されます。
右の引数が 0 なら ZeroDivisionError 例外を送出します。
引数には浮動小数点数も使えます。
例えば 3.14%0.7 は 0.34 です (3.14 が 4*0.7 + 0.34 と等しいためです)。
剰余演算子の結果は常に第 2 オペランドと同じ符号を持つか、0 になります。
結果の絶対値は第 2 オペランドの絶対値より小さくなります [1]。
切り捨て除算演算と剰余演算は、恒等式: x == (x//y)*y + (x%y) の関係にあります。切り捨て除算や剰余はまた、組み込み関数 divmod(): divmod(x, y) == (x//y, x%y) とも関係しています。 [2] 。
% 演算子は、数値に対する剰余演算を行うのに加えて、文字列 (string) オブジェクトにオーバーロードされ、旧式の文字列の書式化 (いわゆる補間) を行います。文字列の書式化の構文は Python ライブラリリファレンス printf 形式の文字列書式化 節を参照してください。
剰余 演算は、特殊メソッド __mod__() と __rmod__() でカスタマイズできます。
複素数には、切り捨て除算演算子、剰余演算子、divmod() 関数は定義されていません。
適切であれば、代わりに abs() 関数で浮動小数点数に変換してください。
+ (加算) 演算子は引数の和を返します。
引数は両方とも数値か、両方とも同じ型のシーケンスでなければなりません。
前者では、数値を 共通の実数型に変換 してから足し合わせます。
後者では、シーケンスを連結します。
この演算は、特殊メソッド __add__() と __radd__() でカスタマイズできます。
バージョン 3.14 で変更: 片方のオペランドだけが複素数の場合、もう一方のオペランドは浮動小数点数に変換されます。
- (減算) 演算子は引数の差を返します。
数値の引数は最初に 共通の実数型に変換 されます。
この演算は、特殊メソッド __sub__() と __rsub__() でカスタマイズできます。
バージョン 3.14 で変更: 片方のオペランドだけが複素数の場合、もう一方のオペランドは浮動小数点数に変換されます。
6.8. シフト演算 (shifting operation)¶
シフト演算は、算術演算よりも低い優先順位を持っています:
shift_expr:a_expr|shift_expr("<<" | ">>")a_expr
これらの演算子は整数を引数に取ります。 第 1 引数を、第 2 引数で指定したビット数だけ左または右にシフトします。
左シフト演算は特殊メソッド __lshift__() と __rlshift__() でカスタマイズできます。
右シフト演算は特殊メソッド __rshift__() と __rrshift__() でカスタマイズできます。
n ビットの右シフトは、pow(2,n) による切り捨て除算として定義されます。
n ビットの左シフトは、pow(2,n) による乗算として定義されます。
6.9. ビット単位演算の二項演算 (binary bitwise operation)¶
以下の三つのビット単位演算には、それぞれ異なる優先順位レベルがあります:
and_expr:shift_expr|and_expr"&"shift_exprxor_expr:and_expr|xor_expr"^"and_expror_expr:xor_expr|or_expr"|"xor_expr
& 演算子は、引数のビット単位の AND を返します。
引数は整数であるか、少なくとも一方が特殊メソッド __and__() または __rand__() をオーバーライドした独自のオブジェクトでなければなりません。
^ 演算子は、引数のビット単位の XOR (排他的 OR) を返します。
引数は整数であるか、少なくとも一方が特殊メソッド __xor__() または __rxor__() をオーバーライドした独自のオブジェクトでなければなりません。
| 演算子は、引数のビット単位の (包含的) OR を返します。
引数は整数であるか、少なくとも一方が特殊メソッド __or__() または __ror__() をオーバーライドした独自のオブジェクトでなければなりません。
6.10. 比較¶
C 言語と違って、Python における比較演算子は同じ優先順位をもっており、全ての算術演算子、シフト演算子、ビット単位演算子よりも低くなっています。また a < b < c が数学で伝統的に用いられているのと同じ解釈になる点も C 言語と違います:
comparison:or_expr(comp_operatoror_expr)* comp_operator: "<" | ">" | "==" | ">=" | "<=" | "!=" | "is" ["not"] | ["not"] "in"
比較はブール値 True または False を返します。
独自の 拡張比較メソッド は、ブール値以外を返す場合があります。
この場合、真偽値が必要な文脈では、Python はその値に bool() を呼び出します。
比較はいくらでも連鎖することができます。例えば 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 も (読みやすいとは限りませんが) 完全に有効です。
6.10.1. 値の比較¶
演算子 <, >, ==, >=, <=, および != は2つのオブジェクトの値を比較します。
オブジェクトが同じ型を持つ必要はりません。
オブジェクト、値、および型 の章では、オブジェクトは (型や id に加えて) 値を持つことを述べています。 オブジェクトの値は Python ではやや抽象的な概念です: 例えば、オブジェクトの値にアクセスする正統な方法はありません。 また、その全てのデータ属性から構成されるなどの特定の方法で、オブジェクトの値を構築する必要性もありません。 比較演算子は、オブジェクトの値とは何かについての特定の概念を実装しています。 この比較の実装によって、間接的にオブジェクトの値を定義していると考えることもできます。
すべての型は object の直接または間接のサブタイプなので、object からデフォルトの比較動作を継承します。
型は 基本的なカスタマイズ で説明する __lt__() などの 拡張比較メソッド を実装して、比較動作をカスタマイズできます。
等価比較 (== および !=) のデフォルトの振る舞いは、オブジェクトの同一性に基づいています。
従って、同一のインスタンスの等価比較の結果は等しいとなり、同一でないインスタンスの等価比較の結果は等しくないとなります。
デフォルトの振る舞いをこのようにしたのは、全てのオブジェクトを反射的 (reflexive つまり x is y ならば x == y) なものにしたかったからです。
デフォルトの順序比較 (<, >, <=, >=) は提供されません; 比較しようとすると TypeError が送出されます。
この振る舞いをデフォルトの振る舞いにした動機は、等価性と同じような不変性が欠けているからです。
同一でないインスタンスは常に等価でないとする等価比較のデフォルトの振る舞いは、型が必要とするオブジェクトの値や値に基づいた等価性の実用的な定義とは対照的に思えるでしょう。 そのような型では比較の振る舞いをカスタマイズする必要が出てきて、実際にたくさんの組み込み型でそれが行われています。
次のリストでは、最重要の組み込み型の比較の振る舞いを解説しています。
いくつかの組み込みの数値型 (数値型 int, float, complex) と標準ライブラリの型
fractions.Fractionおよびdecimal.Decimalは、これらの型の範囲で異なる型とも比較できますが、複素数では順序比較がサポートされていないという制限があります。 関わる型の制限の範囲内では、精度のロス無しに数学的に (アルゴリズム的に) 正しい比較が行われます。非数値である
float('NaN')とdecimal.Decimal('NaN')は特別です。 数と非数値との任意の順序比較は偽です。 直観に反する帰結として、非数値は自分自身と等価ではないことになります。 例えばx = float('NaN')ならば、3 < x,x < 3,x == xは全て偽で、x != xは真です。 この振る舞いは IEEE 754 に従ったものです。NoneとNotImplementedはシングルトンです。 PEP 8 は、シングルトンの比較には等価演算子を使わず、常にisまたはis notを使うことを推奨しています。バイナリシーケンス (
bytesまたはbytearrayのインスタンス) は、これらの型の範囲で異なる型とも比較できます。 比較は要素の数としての値を使った辞書式順序で行われます。文字列 (
strのインスタンス) の比較は、文字の Unicode のコードポイントの数としての値 (組み込み関数ord()の返り値) を使った辞書式順序で行われます。 [3]文字列とバイナリシーケンスは直接には比較できません。
シーケンス (
tuple,list, orrangeのインスタンス) の比較は、同じ型どうしでしか行えず、 range は順序比較をサポートしていません。 異なる型どうしの等価比較の結果は等価でないとなり、異なる型どうしの順序比較はTypeErrorを送出します。シーケンスは、対応する要素を比較して辞書式に比較します。 組み込みコンテナは通常、同一のオブジェクトはそれ自身と等しいとみなします。 これにより、同一のオブジェクトに対する等価性の検査を省いて性能を高め、内部の不変条件を保てます。
組み込みのコレクションどうしの辞書式比較は次のように動作します:
比較の結果が等価となる2つのコレクションは、同じ型、同じ長さ、対応する要素どうしの比較の結果が等価でなければなりません (例えば、
[1,2] == (1,2)は型が同じでないので偽です)。順序比較をサポートしているコレクションの順序は、最初の等価でない要素の順序と同じになります (例えば、
[1,2,x] <= [1,2,y]はx <= yと同じ値になります)。 対応する要素が存在しない場合、短い方のコレクションの方が先の順序となります (例えば、[1,2] < [1,2,3]は真です)。
マッピング (
dictのインスタンス) の比較の結果が等価となるのは、同じ(key, value)を持っているときかつそのときに限ります。 キーと値の等価比較では反射性が強制されます。順序比較 (
<,>,<=,>=) はTypeErrorを送出します。集合 (
setまたはfrozensetのインスタンス) の比較は、これらの型の範囲で異なる型とも行えます。集合には、部分集合あるいは上位集合かどうかを基準とする順序比較が定義されています。 この関係は全順序を定義しません (例えば、
{1,2}と{2,3}という2つの集合は片方がもう一方の部分集合でもなく上位集合でもありません)。 従って、集合は全順序性に依存する関数の引数として適切ではありません (例えば、min(),max(),sorted()は集合のリストを入力として与えると未定義な結果となります)。集合の比較では、その要素の反射性が強制されます。
他の組み込み型のほとんどは比較メソッドが実装されておらず、デフォルトの比較の振る舞いを継承します。
比較の振る舞いをカスタマイズしたユーザ定義クラスは、可能なら次の一貫性の規則に従う必要があります:
等価比較は反射的でなければなりません。 つまり、同一のオブジェクトは等しくなければなりません:
x is yならばx == y比較は対称的でなければなりません。 つまり、以下の式の結果は同じでなければなりません:
x == yとy == xx != yとy != xx < yとy > xx <= yとy >= x比較は推移的でなければなりません。 以下の (包括的でない) 例がその説明です:
x > y and y > zならばx > zx < y and y <= zならばx < z比較の逆は真偽値の否定でなければなりません。 つまり、以下の式の結果は同じでなければなりません:
x == yとnot x != yx < yとnot x >= y(全順序の場合)x > yとnot x <= y(全順序の場合)最後の 2 つの式は、全順序が定義されたコレクションに適用されます (例えばシーケンスには適用されますが、集合やマッピングには適用されません)。
@~functools.total_orderingデコレータも参照してください。hash()の結果は等価性と一貫している必要があります。 等価なオブジェクトどうしは同じハッシュ値を持つか、ハッシュ値が計算できないものとされる必要があります。
Python はこの一貫性規則を強制しません。 事実、非数値がこの規則に従わない例となります。
6.10.2. 所属検査演算¶
演算子 in および not in は所属関係を調べます。
x in s の評価は、 x が s の要素であれば True となり、そうでなければ False となります。
x not in s は x in s の否定を返します。
すべての組み込みのシーケンス型と集合型に加えて、辞書も in を辞書が与えられたキーを持っているかを調べる演算子としてサポートしています。
リスト、タプル、集合、凍結集合、辞書、 collections.deque のようなコンテナ型において、式 x in y は any(x is e or x == e for e in y) と等価です。
文字列やバイト列型については、 x in y は x が y の部分文字列であるとき、かつそのときに限り True になります。これは y.find(x) != -1 と等価です。空文字列は、他の任意の文字列の部分文字列とみなされます。従って "" in "abc" は True を返すことになります。
__contains__() メソッドを定義したユーザー定義クラスでは、y.__contains__(x) が真の値を返せば x in y は True を返し、それ以外では False を返します。
__contains__() を定義せず __iter__() を定義したユーザー定義クラスでは、
y をイテレートしたときに x is z or x == z が真になる値 z が得られれば、x in y は True です。
イテレート中に例外が送出された場合は、in がその例外を送出したのと同じになります。
最後に、旧式のイテレーションプロトコルを試します。
クラスが __getitem__() を定義している場合、
x is y[i] or x == y[i] となる非負整数のインデックス i があり、それより小さいインデックスで IndexError 例外が送出されなければ、そのときに限り x in y は True です。
(その他の例外が送出された場合は、in がその例外を送出したのと同じになります。)
6.10.3. 同一性の比較¶
演算子 is および is not は、オブジェクトの同一性に対するテストを行います: x is y は、 x と y が同じオブジェクトを指すとき、かつそのときに限り真になります。
オブジェクトの同一性は id() 関数を使って判定されます。
x is not y は is の真値を反転したものになります。 [4]
6.11. ブール演算 (boolean operation)¶
or_test:and_test|or_test"or"and_testand_test:not_test|and_test"and"not_testnot_test:comparison| "not"not_test
ブール演算や制御フロー文で式を使う場合、False、None、すべての数値型の 0、空の文字列とコンテナ (文字列、タプル、リスト、辞書、集合、凍結集合を含む) は偽と解釈されます。
その他の値はすべて真と解釈されます。
ユーザー定義オブジェクトは __bool__() メソッドを提供して、真偽値をカスタマイズできます。
演算子 not は、引数が偽である場合には True を、それ以外の場合には False になります。
式 x and y は、まず x を評価します; x が偽なら x の値を返します; それ以外の場合には、 y を評価した結果値を返します。
式 x or y は、まず x を評価します; x が真なら x の値を返します; それ以外の場合には、 y を評価した結果値を返します。
なお、 and も or も、返す値を True や False に制限せず、最後に評価した引数を返します。
この仕様が便利なときもあります。例えば s が文字列で、空文字列ならデフォルトの値に置き換えたいとき、式 s or 'foo' は望んだ値を与えます。
not は必ず新しい値を作成するので、引数の型に関係なくブール値を返します (例えば、 not 'foo' は '' ではなく False になります)。
6.12. 代入式¶
assignment_expression: [identifier":="]expression
代入式 (「名前付き式」や「セイウチ」とも呼ばれます) は、expression を identifier に代入すると同時に、その expression の値を返します。
よくある用途の 1 つは、正規表現にマッチした結果の処理です。
if matching := pattern.search(data):
do_something(matching)
ファイルストリームを一定量ずつ処理する場合にも使えます。
while chunk := file.read(9000):
process(chunk)
代入式を式文として使う場合や、スライス、条件式、ラムダ式、キーワード引数、内包表記の if 条件の部分式として使う場合、
また assert 文、with 文、代入文の中で使う場合は、丸括弧で囲む必要があります。
使用できるその他の場所では、if 文や while 文を含め、丸括弧は不要です。
Added in version 3.8: 代入式に関してより詳しくは PEP 572 を参照してください。
6.13. 条件式 (Conditional Expressions)¶
conditional_expression:or_test["if"or_test"else"expression] expression:conditional_expression|lambda_expr
条件式 (「三項演算子」とも呼ばれます) は、if-else 文の代わりに使えます。 式なので値を返し、部分式としても使えます。
x if C else y という式は最初に x ではなく条件 C を評価します。 C が true の場合 x が評価され値が返されます。 それ以外の場合には y が評価され返されます。
条件演算に関してより詳しくは PEP 308 を参照してください。
6.14. ラムダ (lambda)¶
lambda_expr: "lambda" [parameter_list] ":"expression
ラムダ式 (ラムダ形式とも呼ばれます) は無名関数を作成するのに使います。
式 lambda parameters: expression は関数オブジェクトになります。
この無名オブジェクトは以下に定義されている関数オブジェクト同様に動作します:
def <lambda>(parameters):
return expression
引数の一覧の構文は 関数定義 を参照してください。ラムダ式で作成された関数は文やアノテーションを含むことができない点に注意してください。
6.15. 式のリスト¶
starred_expression: "*"or_expr|expressionflexible_expression:assignment_expression|starred_expressionflexible_expression_list:flexible_expression(","flexible_expression)* [","] starred_expression_list:starred_expression(","starred_expression)* [","] expression_list:expression(","expression)* [","] yield_list:expression_list|starred_expression"," [starred_expression_list]
リスト表示や集合表示の一部である場合を除き、少なくとも 1 個のカンマを含む式リストはタプルになります。 タプルの長さは式リストに含まれる式の数です。 式は左から右へ評価されます。
An asterisk * denotes iterable unpacking. Its operand must be
an iterable. The iterable is expanded into a sequence of items,
which are included in the new tuple, list, or set, at the site of
the unpacking.
Added in version 3.5: 式リストでのイテラブルのアンパックは最初に PEP 448 で提案されました。
Added in version 3.11: 式リストのどの項目にもアスタリスクを付けられるようになりました。 PEP 646 を参照してください。
末尾のカンマが必須なのは、1, のような要素が 1 個のタプルを作る場合だけです。
その他の場合は省略できます。
1 個の式に末尾のカンマを付けなければ、タプルではなく、その式の値になります。
(空のタプルを作るには、空の丸括弧の組 () を使います。)
6.16. 評価順序¶
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
6.17. 演算子の優先順位¶
以下の表は Python における演算子の優先順位を要約したものです。優先順位の最も高い (結合が最も強い) ものから最も低い (結合が最も弱い) ものに並べてあります。同じボックス内の演算子の優先順位は同じです。構文が明示的に示されていないものは二項演算子です。同じボックス内の演算子は、左から右へとグループ化されます (例外として、べき乗および条件式は右から左にグループ化されます)。
比較 節で述べられているように、比較、所属、同一性のテストは全てが同じ優先順位を持っていて、左から右に連鎖するという特徴を持っていることに注意してください。
演算子 |
説明 |
|---|---|
|
結合式または括弧式、リスト表示、辞書表示、集合表示 |
|
添字表記 (スライス表記を含む)、呼び出し、属性参照 |
Await 式 |
|
|
べき乗 [5] |
|
正数、負数、ビット単位 NOT |
|
乗算、行列乗算、除算、切り捨て除算、剰余 [6] |
|
加算および減算 |
|
シフト演算 |
|
ビット単位 AND |
|
ビット単位 XOR |
|
ビット単位 OR |
所属や同一性のテストを含む比較 |
|
ブール演算 NOT |
|
ブール演算 AND |
|
ブール演算 OR |
|
|
条件式 |
ラムダ式 |
|
|
代入式 |
脚注