Python代入が式ではなくステートメントであるのはなぜですか?代入の右側の値を返す式であった場合、場合によっては、非常に冗長なコードが許可されていました。 。見えない問題はありますか?
例えば:
# lst is some sequence
# X is come class
x = X()
lst.append(x)
次のように書き直すことができます。
lst.append(x = X())
正確には、x
がキーワード引数として扱われるため、上記は機能しません。しかし、別のペアのかっこ(またはキーワード引数の別の記号)は、それを解決します。
特にPythonのような言語では、割り当てが式であると感じている人はたくさんいます(any値は条件で許可されています(ブール型の値だけではありません))、エラーが発生しやすいです。おそらく、Guidoはそのように感じる人の中にいる/いました。古典的なエラーは次のとおりです。
if x = y: # oops! meant to say ==
Pythonは、変数への最初の割り当てもその宣言であるため、Cのような言語よりもPythonの方が、状況は少し複雑です。 。 例えば:
def f():
print x
def g():
x = h()
print x
これら2つの関数では、「print x
"行はさまざまなことを行います。1つはグローバル変数x
を参照し、もう1つはローカル変数x
を参照します。x
のg
割り当てのためにローカルです。割り当てをより大きな式/ステートメントの中に埋め込むことが可能である場合、これはさらに混乱する可能性があります(以前よりも)。
現実の答え:それは必要ありません。
Cでこれが見られるケースのほとんどは、エラー処理が手動で行われるためです。
if((fd = open("file", O_RDONLY)) == -1)
{
// error handling
}
同様に、多くのループが書かれている方法について:
while(i++ < 10)
;
これらの一般的なケースは、Pythonでは異なる方法で実行されます。エラー処理は通常、例外処理を使用します。ループは通常、反復子を使用します。
これに対する議論は必ずしも重大なものではありませんが、Pythonではそれが単にそれほど重要ではないという事実に反論しています。
(x := y)
式のサポートは、Pythonの近い将来のバージョンで実装される予定です。 Guidoは最近、Pythonでの割り当て式をサポートするという提案 PEP 572 を2018年7月に受け入れました。 (撤回 PEP 379 など、以前の提案もあった。)
バージョン3までは、print
も式ではなくステートメントだったことを思い出してください。
注:ステートメントx = y = z
は、同じ値を複数のターゲット(または、複数のtarget)に割り当てます-lists(アンパッキングも許可されているため)はすでにpythonで長くサポートされていましたが、連続する代入サブ式をチェーンするのではなく、特別な syntax として実装されました。 (実際、個々の割り当てが実行される順序は逆になります。)
これは、特定の古典的なエラーを防ぐために、Guido側で意図的に行われたものだと思います。例えば。
if x = 3: print x
あなたが実際に言うつもりだったとき
if x == 3: ...
私はそれがうまくいくことを望みましたが、私は{
および}
コードブロックを囲みますが、変更されることはありません。
割り当てが式である場合、これらおよび他の多くの機能を再調整する必要があります。私にとっては、そのような可読コードと便利な機能を得るためにあなたがしなければならない取引のようなものです。持つために
if a and (h not in b): ...
のではなく
if (a && !(h in b)) { ... }
[クラシック(a = b:の場合)の種類のエラーについて話していません。]