Pythonの面白い時、これらのコードはあなたに「寝槽、どうしてこんなことになったの?」


Pythonは分かりやすい言語ですが、これは私たちPythonに暗い料理がないという意味ではありません.次に、「臥槽、どうしてこんなことになったのか」と叫ぶプログラムをいくつか選びました.これらの例は面白いだけでなく、Pythonの詳細に対する理解を深めることができます.あなた自身が説明できるかどうかを見てみましょう.
以下のコードを信じない場合は、手動で試してください.テスト環境:Python 3.6
20と21の違いは何ですか?
In [1]: 'a' * 20 is 'aaaaaaaaaaaaaaaaaaaa'
Out[1]: True

In [2]: 'a' * 21 is 'aaaaaaaaaaaaaaaaaaaaa'
Out[2]: False

初めてこの例を見たとき、私の心はwtfに満ちていました.20と21の違いは何ですか.どうして結果が違いますか.なぜなら、pythonは内部最適化を行う際に定数置換の操作を行い、すなわち「a」*20という文を「aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
1つの関数Returnを2回
In [3]: def some_func():
   ...:     try:
   ...:         return 'from_try'
   ...:     finally:
   ...:         return 'from_finally'
   ...:     

In [4]: some_func()
Out[4]: 'from_finally'

一般的なPythonチュートリアルでは、関数が最初のreturnに実行されると終了し、残りの文は実行されません.しかし、もしそうなら、上のコードで私たちのsomefunc()が返すべきは'from_です.try’ですが、結果は違います.この現象の原因はfinallyの後の文が永遠に実行され、関数の戻り値は最後のreturn文によって決定されるため、関数の戻り値はfinally文の戻り値である.
何回ループしますか?
次のコードは何回ループすると思いますか?
for i in range(4):
    print(i)
    i = 10

一部の学生は1回しか循環しないと推測して、正しい出力は
0
1
2
3

4回もループしているので、i=10という文は全く役に立たないのでしょうか?はい、これはPythonのforループのメカニズムに関係しています.ループ体の前に、次の必要な値が先に生成され、ループ変数、ここでiに値が与えられます.すなわち,循環体にはi=10が1つあるが,次の循環前にforはi=2またはi=3の操作を行い,i=10を覆う.
一石三鳥
row = [''] * 3
board = [row] * 3
print(board)
==> [['', '', ''], ['', '', ''], ['', '', '']]

最初の要素に値を付けて結果を見てみましょう
board[0][0] = 'X'
print(board)
==> [['X', '', ''], ['X', '', ''], ['X', '', '']]

What?どうして3つの要素がXになったのか、私たちは値に値をつけたのに.これは、[row]*3という操作が実際にrowをコピーすることなく、3つのobject reference、すなわちboard[0]board[1]board[2]という3つの要素が実際に同じリストrowを指しているためであり、board[0][0]を変更することはrow[0]を変更することであり、board[1][0]board[2][0]を同時に変更することになる.
また数字ですが、256と257の違いは何ですか?
In [45]: a = 256
In [46]: b = 256
In [47]: a is b
Out[47]: True

In [48]: a = 257
In [49]: b = 257
In [50]: a is b
Out[50]: False

In [58]: a, b = 257, 257
In [59]: a is b
Out[59]: True

何があったんだ?これはまたPythonのもう一つの最適化メカニズムを引き出し、解釈器が始まると-5から256の数字が初期化されます.これらの数字はよく使われているからです.したがってa=256は実際にはaを作成された256に向けており,bも同様である.257は予め作成されておらず、各行のコードは解釈器の中で単独で最適化されているため、b=257と書くと解釈器はすでに257があることを知らず、また1つ新しく作成されたので、彼ら2人は異なるobjectを指している.しかし、1行の中で同時にa bに257の値を割り当てると、解釈器最適化はこの点を知っていて、257しか作成されていないので、a is bはまたTrueになります.補足すると、この現象はreplインタラクティブ実行にのみ存在し、これらの文を1つのファイルに書いて実行すると、コンパイラは一緒に最適化され、すべての結果はTrueになります.