6. 式 (expression)¶
この章では、Python の式における個々の要素の意味について解説します。
構文上の注意: この章以降では、文法の表記法 を字句解析ではなく構文の記述に使います。
構文規則の (選択肢の 1 つの) 形式が次のように記述され、
name: othername
で記述されていて、この構文特有の意味付け (semantics) が記述されていない場合、 name の形式をとる構文の意味付けは othername の意味付けと同じになります。
6.1. 算術変換 (arithmetic conversion)¶
以下の算術演算子の説明で「数値の引数を共通の実数型に変換する」とある場合、組み込みの数値型に対する演算子の実装が、標準ライブラリのドキュメントの 数値型 の節で説明するとおりに動作することを意味します。
特定の演算子や数値以外のオペランド (例えば % 演算子の左オペランドとしての文字列) には、追加の規則が適用されます。
拡張では独自の変換動作を定義する必要があります。
6.2. アトム、原子的要素 (atom)¶
アトムは式の最も基本的な要素です。 最も単純なアトムは 組み込み定数、名前、リテラル です。 より複雑なアトムは、対になるデリミタで囲みます。
形式的には、アトムの構文は次のとおりです。
atom: |builtin_constant|identifier|literal|parenthesized_enclosure|bracketed_enclosure|braced_enclosureparenthesized_enclosure: |group|tuple|yield_atom|generator_expressionbracketed_enclosure: |listcomp|listbraced_enclosure: |dictcomp|dict|setcomp|set
6.2.1. 組み込み定数¶
キーワード True、False、None は 組み込み定数 の名前です。
トークン ... は Ellipsis 定数を表します。
これらのアトムを評価すると、対応する値が得られます。
注釈
グローバル変数として利用できる組み込み定数はほかにもありますが、キーワード なのはここで挙げたものだけです。 特に、これらの名前には再代入できず、属性としても使えません。
>>> False = 123
File "<input>", line 1
False = 123
^^^^^
SyntaxError: cannot assign to False
形式的には、組み込み定数の構文は次のとおりです。
builtin_constant: 'True' | 'False' | 'None' | '...'
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. 丸括弧で囲んだグループ¶
丸括弧で囲んだグループ は、式を丸括弧で囲んだものです。 グループを評価すると、内側の式と同じ値が得られます。
数学の記法と同様、グループは 演算子の優先順位 を変更したり明確にしたりするために使います。 例えば次のように書きます。
>>> 3 << 2 | 4
12
>>> 3 << (2 | 4) # | (ビット単位の OR) の優先順位を変更
192
>>> (3 << 2) | 4 # 丸括弧なしと同じ (ただしより明確)
12
丸括弧で囲まれたものがすべて グループ になるわけではありません。 丸括弧で囲んだグループには、式をちょうど 1 個含める必要があり、末尾にカンマは置けません。 ほかの丸括弧を使う形式については タプル表示 と ジェネレータ式 を参照してください。
形式的には、グループの構文は次のとおりです。
group: '(' assignment_expression ')'
6.2.5. コンテナ表示¶
組み込みのコンテナ (リスト、集合、タプル、辞書) を構築するために、Python は 表示 と呼ぶ特別な構文を提供します。 4 種類の表示には細かな違いがあり、以降の節で詳しく説明します。 ただし、どの表示もカンマで区切った項目を対になるデリミタで囲んだものです。
例えば リスト表示 は、式の並びを角括弧で囲んだものです。
>>> ["one", "two", "three"]
['one', 'two', 'three']
>>> [1 + 2, 2 + 3]
[3, 5]
リスト表示、タプル表示、辞書表示では項目を空にできます (集合表示ではできません)。
>>> [] # 空のリスト
[]
>>> () # 空のタプル
()
>>> {} # 空の辞書
{}
項目の並びが空でなければ、最後の項目の後にカンマを追加できます。 このカンマに効果はありません。
>>> ["one", "two", "three",] # "three" の後のカンマに注意
['one', 'two', 'three']
注釈
(非明示的な行継続 を使って) 複数の行にわたる表示では、末尾のカンマをよく使います。 将来、末尾に項目を追加するときに、既存の行を変更せずに済むためです。
>>> [
... 'one',
... 'two',
... 'three',
... ]
['one', 'two', 'three']
実行時に表示を評価すると、列挙された項目を左から右に評価し、適切な型の新しいコンテナに格納します。
タプル表示、リスト表示、集合表示では、どの項目の前にもアスタリスク (*) を付けられます (辞書表示では使えません)。
これは イテラブルのアンパック を表します。
実行時には、アスタリスク付きの式の評価結果はイテラブルでなければならず、その内容がアンパックを記述した位置でコンテナに挿入されます。
例えば次のように書きます。
>>> numbers = (1, 2)
>>> [*numbers, 'word', *numbers]
[1, 2, 'word', 1, 2]
辞書表示には、二重のアスタリスク (**) で表す 辞書のアンパック という同様の仕組みがあります。
詳細は 辞書表示 を参照してください。
さらに高度な表示の形式として、内包表記 があります。 項目を一連の繰り返しやフィルタリングの指示に従って計算します。 詳細は 内包表記 (Comprehension) の節を参照してください。
Added in version 3.5: 表示内でのイテラブルと辞書のアンパックを導入しました。 最初に PEP 448 で提案されました。
6.2.5.1. リスト表示¶
リスト表示 は、式の並びを角括弧で囲んだものです。 空でも構いません。 例えば次のように書きます。
>>> ["one", "two", "three"]
['one', 'two', 'three']
>>> ["one"] # 要素が 1 個のリスト
['one']
>>> [] # 空のリスト
[]
表示全般については コンテナ表示 を参照してください。
リスト表示の形式文法は次のとおりです。
list: '[' [flexible_expression_list] ']'
6.2.5.2. 集合表示¶
集合表示 は、空ではない 式の並びを波括弧で囲んだものです。 例えば次のように書きます。
>>> {"one", "two", "three"}
{'one', 'three', 'two'}
>>> {"one"} # 要素が 1 個の集合
{'one'}
表示全般については コンテナ表示 を参照してください。
空集合を表す特別な構文はありません。
{} リテラルは、空の辞書を構築する 辞書表示 です。
空集合を作るには、引数なしで set() を呼び出してください。
集合表示の形式文法は次のとおりです。
set: '{' flexible_expression_list '}'
6.2.5.3. タプル表示¶
タプル表示 は、式の並びを丸括弧で囲んだものです。 例えば次のように書きます。
>>> (1, 2)
(1, 2)
>>> () # 空のタプル
()
表示全般については コンテナ表示 を参照してください。
曖昧さを避けるため、要素がちょうど 1 個のタプル表示には末尾のカンマが必要です。 カンマがなければ 丸括弧で囲んだグループ になります。
>>> ('single',) # 要素が 1 個のタプル
('single',)
>>> ('single') # カンマなし: 単一の文字列
'single'
言い換えると、タプル表示は、次のいずれかの並びを丸括弧で囲んだものです。
カンマで区切った 2 個以上の式。
各式の後にカンマを付けた、0 個以上の式。
タプルは不変なので、リテラルのオブジェクトの同一性の規則 はタプルにも適用されます。 実行時に、同じ値を持つタプルが 2 か所に現れても、同じオブジェクトになる場合とならない場合があります。
注釈
Python の構文には 式リスト もあります。 カンマで区切った式の並びを丸括弧で 囲まず に書き、評価するとタプルになります。
つまり、タプルの構文では丸括弧よりカンマのほうが重要です。 カンマを使わずに書くのは空のタプルだけです。
タプル表示の形式文法は次のとおりです。
tuple: | '('flexible_expression(','flexible_expression)+ [','] ')' | '('flexible_expression',' ')' | '(' ')'
6.2.5.4. 辞書表示¶
辞書表示 は、辞書項目 の並びを波括弧で囲んだものです。 空でも構いません。 各辞書項目は、キー とそれに対応する 値 という 2 つの式をコロンで区切ったものです。 例えば次のように書きます。
>>> {1: 'one', 2: 'two'}
{1: 'one', 2: 'two'}
At runtime, when a dictionary comprehension is evaluated, the expressions are evaluated from left to right. 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 comprehension, and the final dictionary's value for a given key will be the last one given. For example:
>>> {
... 1: 'this will be overridden',
... 2: 'two',
... 1: 'also overridden',
... 1: 'one',
... }
{1: 'one', 2: 'two'}
辞書項目にはキーと値のペアの代わりに、二重のアスタリスク ** を前に付けた式も使えます。
これは 辞書のアンパック を表します。
実行時に式の評価結果は mapping でなければならず、マッピングの各項目が新しい辞書に追加されます。
キーと値のペアと同様に、後の値は、先に現れた項目やアンパックによって設定済みの値を置き換えます。
デフォルト値の一部を上書きするために使えます。
>>> defaults = {'color': 'blue', 'count': 8}
>>> overrides = {'color': 'yellow'}
>>> {**defaults, **overrides}
{'color': 'yellow', 'count': 8}
Added in version 3.5: 辞書表示のアンパックは最初に PEP 448 で提案されました。
辞書表示の形式文法は次のとおりです。
dict: '{' [double_starred_kvpairs] '}' double_starred_kvpairs: ','.double_starred_kvpair+ [','] double_starred_kvpair: '**'or_expr|kvpairkvpair:expression':'expression
6.2.6. 内包表記 (Comprehension)¶
リスト、集合、辞書の 内包表記 は コンテナ表示 の一種です。 項目を明示的に列挙する代わりに、一連の繰り返しやフィルタリングの指示に従って計算します。
最も単純な内包表記は、1 個の式と、その後に続く for 節からなります。
for 節の構文は、末尾のコロンを除いて for 文 のヘッダと同じです。
例えば、最初の 10 個の平方数のリストは次のように書けます。
>>> [x**2 for x in range(10)]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
実行時にリスト内包表記は新しいリストを作成します。
in の後の式の評価結果は iterable でなければなりません。
このイテラブルの各要素を、for 文と同様に for 節のターゲットに束縛します。
続いて、そのターゲットがスコープ内にある状態で for の前の式を評価し、結果を新しいリストに追加します。
従って、上の例はおおよそ次の関数を定義して呼び出すことに相当します。
def make_list_of_squares(iterable):
result = []
for x in iterable:
result.append(x**2)
return result
make_list_of_squares(range(10))
集合内包表記も同様に動作します。 例えば次は小文字の集合です。
>>> {x.lower() for x in ['a', 'A', 'b', 'C']}
{'c', 'a', 'b'}
実行時には、おおよそ次の関数を呼び出すことに相当します。
def make_lowercase_set(iterable):
result = set(iterable)
for x in iterable:
result.append(x.lower())
return result
make_lowercase_set(['a', 'A', 'b', 'C'])
辞書内包表記は、1 個の式ではなく、コロンで区切ったキーと値のペアで始まります。 例えば次のように書きます。
>>> {func.__name__: func for func in [print, hex, any]}
{'print': <built-in function print>,
'hex': <built-in function hex>,
'any': <built-in function any>}
実行時には、おおよそ次に相当します。
def make_dict_mapping_names_to_functions(iterable):
result = {}
for func in iterable:
result[func.__name__] = func
return result
iterable([print, hex, any])
その他の辞書表示と同様、同じキーを複数回指定できます。 先の値は、後で評価される値で上書きされます。
タプル内包表記 はありません。 似た構文は ジェネレータ式 に使われ、次のようにしてタプルを構築できます。
>>> tuple(x**2 for x in range(10))
(0, 1, 4, 9, 16, 25, 36, 49, 64, 81)
バージョン 3.8 で変更: Python 3.8 より前のバージョンでは、辞書内包表記において、キーと値の評価順序は明示されていませんでした。CPython では、値がキーより先に評価されていました。バージョン 3.8 からは PEP 572 で提案されているように、キーが値より先に評価されます。
6.2.6.1. 内包表記でのフィルタリング¶
for 節の後には、式を伴う if 節を続けられます。
例えば、math モジュール内の f で始まる名前のリストは次のように書けます。
>>> [name for name in vars(math) if name.startswith('f')]
['fabs', 'factorial', 'floor', 'fma', 'fmod', 'frexp', 'fsum']
実行時には、結果のコンテナに各要素を追加する前に if の後の式を評価し、偽ならその要素をスキップします。
従って、上の例はおおよそ次の関数を定義して呼び出すことに相当します。
def get_math_f_names(iterable):
result = []
for name in iterable:
if name.startswith('f'):
result.append(name)
return result
get_math_f_names(vars(math))
フィルタリングは、より複雑な内包表記の特別な場合です。 より形式的な説明は次の節を参照してください。
6.2.6.2. 複雑な内包表記¶
一般に、内包表記の最初の for 節の後には、0 個以上の for 節や if 節を追加できます。
例えば次は、2 つの Python モジュールが公開する名前から、a で始まるものだけを選んだリストです。
>>> import array
>>> import math
>>> [
... name
... for module in [array, math]
... for name in vars(module)
... if name.startswith('a')
... ]
['array', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh']
実行時には、おおよそ次を定義して呼び出すことに相当します。
def get_a_names(iterable):
result = []
for module in iterable:
for name in vars(module):
if name.startswith('a'):
result.append(name)
return result
get_a_names([array, math])
新しいコンテナの要素は、各 for 節や if 節をブロックとみなして左から右へ入れ子にし、
最も内側のブロックに達するたびに式を評価して得られる要素 (または辞書の項目) です。
一番左の for 節のイテラブルを表す式を除き、内包表記は暗黙的に入れ子になった独立したスコープで実行されます。
そのため、ターゲットリストで代入する名前が、外側のスコープへ「漏れる」ことはありません。
例えば次のようになります。
>>> x = 'old value'
>>> [x**2 for x in range(10)] # この `x` は内包表記のローカル変数
>>> x
'old value'
一番左の for 節のイテラブルを表す式は、外側のスコープで直接評価し、その結果を暗黙的に入れ子になったスコープへ引数として渡します。
後続の for 節や、一番左の for 節に付くフィルタ条件は、
一番左のイテラブルから得た値に依存する可能性があるため、外側のスコープでは評価できません。
内包表記が常に適切な型のコンテナになるのを保証するために、 yield 式や yield from 式は暗黙的な入れ子のスコープでは禁止されています。
内包表記のイテラブルを表す式 (in キーワードの後の式) の中では、代入式 を使えません。
また、クラス定義に直接現れる内包表記では、どの場所にも代入式を使えません。
バージョン 3.8 で変更: yield および yield from は暗黙的な入れ子のスコープでは禁止となりました。
6.2.6.3. 内包表記でのアンパック¶
リスト内包表記や集合内包表記の式にアスタリスクを付けると、その結果を アンパック して 0 個以上の要素を生成します。
リストを「平坦化」するためによく使います。 例えば次のように書きます。
>>> students = ['Petr', 'Blaise', 'Jarka']
>>> teachers = ['Salim', 'Bartosz']
>>> lists_of_people = [students, teachers]
>>> [*people for people in lists_of_people]
['Petr', 'Blaise', 'Jarka', 'Salim', 'Bartosz']
実行時には、この内包表記はおおよそ次に相当します。
def flatten_names(lists_of_people):
result = []
for people in lists_of_people:
result.extend(people)
return result
辞書内包表記では、アスタリスクを 2 個付けた式を評価し、その結果を 辞書のアンパック で展開して、0 個以上のキーと値のペアを新しい辞書に挿入します。 その他の辞書表示と同様、同じキーを複数回指定した場合、結果の辞書でそのキーに対応する値は最後に指定したものになります。
例えば:
>>> system_defaults = {'color': 'blue', 'count': 8}
>>> user_defaults = {'color': 'yellow'}
>>> overrides = {'count': 5}
>>> configuration_sets = [system_defaults, user_defaults, overrides]
>>> {**d for d in configuration_sets}
{'color': 'yellow', 'count': 5}
Added in version 3.15: * 演算子と ** 演算子による内包表記でのアンパックは、PEP 798 で導入されました。
6.2.6.4. 非同期内包表記¶
async def 関数では、async for 節で asynchronous iterator をイテレートできます。
async def 関数内の内包表記は、先頭の式に続いて for 節または async for 節を持ち、
さらに for 節や async for 節を追加したり、await 式を使ったりできます。
内包表記が async for 節を含む場合や、一番左の for 節のイテラブルを表す式以外の場所に await 式や他の非同期内包表記を含む場合、非同期内包表記 と呼びます。
非同期内包表記は、それを含むコルーチン関数の実行を一時停止する場合があります。
Added in version 3.6: 非同期内包表記は PEP 530 で導入されました。
バージョン 3.11 で変更: 非同期関数の内包表記の中でも、非同期内包表記を使えるようになりました。 外側の内包表記も暗黙的に非同期になります。
6.2.6.5. 内包表記の形式文法¶
内包表記の形式文法は次のとおりです。
listcomp: '['comprehension']' setcomp: '{'comprehension'}' comprehension:flexible_expressionfor_if_clause+ dictcomp: | '{'kvpairfor_if_clause+ '}' | '{' '**'expressionfor_if_clause+ '}' for_if_clause: | ['async'] 'for'target_list'in'or_test('if'or_test)*
6.2.7. ジェネレータ式¶
ジェネレータ式 の構文は、角括弧ではなく丸括弧で囲むことを除いて、リスト 内包表記 と同じです。 例えば次のように書きます。
>>> 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: "(" comprehension ")"
Added in version 3.6: 非同期ジェネレータ式が導入されました。
バージョン 3.7 で変更: Python 3.7 より前では、非同期ジェネレータ式は async def コルーチンでしか使えませんでした。
3.7 からは、任意の関数で非同期ジェネレータ式が使えるようになりました。
バージョン 3.8 で変更: yield および yield from は暗黙的な入れ子のスコープでは禁止となりました。
6.2.8. 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.8.1. 使用例¶
以下の簡単なサンプルはジェネレータとジェネレータ関数の振る舞いを実際に紹介します:
>>> 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.8.2. 非同期ジェネレータ関数 (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.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です。- 組み込み関数またはメソッド:
結果はインタプリタに依存します; 組み込み関数やメソッドの詳細は 組み込み関数 (built-in function) を参照してください。
- クラスオブジェクト:
そのクラスの新しいインスタンスが返されます。
- クラスインスタンスメソッド:
対応するユーザ定義の関数が呼び出されます。このとき、呼び出し時の引数リストより一つ長い引数リストで呼び出されます: インスタンスが引数リストの先頭に追加されます。
- クラスインスタンス:
クラスは
__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 個のカンマを含む式リストはタプルになります。 タプルの長さは式リストに含まれる式の数です。 式は左から右へ評価されます。
末尾のカンマが必須なのは、1, のような要素が 1 個のタプルを作る場合だけです。
その他の場合は省略できます。
1 個の式に末尾のカンマを付けなければ、タプルではなく、その式の値になります。
(空のタプルを作るには、空の丸括弧の組 () を使います。)
6.15.1. イテラブルのアンパック¶
式リストやタプル表示、リスト表示、集合表示では、どの式の前にもアスタリスク (*) を付けられます。
これは イテラブルのアンパック を表します。
実行時には、アスタリスクを付けた式の評価結果は iterable でなければなりません。 イテラブルを項目の列に展開し、アンパックを記述した位置で新しいタプル、リスト、集合に加えます。
Added in version 3.5: 式リストでのイテラブルのアンパックは最初に PEP 448 で提案されました。
Added in version 3.11: 式リストのどの項目にもアスタリスクを付けられるようになりました。 PEP 646 を参照してください。
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 |
|
|
条件式 |
ラムダ式 |
|
|
代入式 |
脚注