pythonは解釈言語です!
5662 ワード
コードブロックの詳細(必見)
コードブロックは、pythonコードのセグメントを1つのユニットとして、全体として実行することができる.以下は公式マニュアルの説明です.
したがって、次のタイプのコードブロックがあります.モジュールファイルは、コードブロック である.関数体は、コードブロック である. classの定義はコードブロック であるインタラクティブ(python idle)の各コマンドラインは、独立したコードブロック である.スクリプトファイルは、コードブロック です.スクリプトコマンドは、コードブロック(python-c「xxx」) です. eval()とexec()の内容もそれぞれのコードブロック がある.
コードブロックの役割は、コードを組織することであり、コードブロック範囲を終了すると、役割ドメイン範囲を終了することを意味する.たとえば、関数ブロックを終了すると、関数の役割ドメインが終了し、関数内のローカル変数が関数の外部にアクセスできなくなります.
また、pythonは解釈言語で、1行を読んで1行を解釈します.これは、1行を読むたびに前の行を忘れることを意味します.しかし、実際には、より厳密には、1つのコードブロックを読んで1つのコードブロックを解釈することであり、これは、コードブロックの内容を読むときに、このコードブロックの中で読んだ内容に属していることを一時的に覚え、完全なコードブロックを読んでから、このコードブロックを統一的に解釈することを意味する.
まず、pythonのインタラクティブツールidleツールでのみテストできるコードブロックに属する行を読む場合について説明します.
理論的にはセミコロンは文の区切り記号であり、結果には影響しません.しかし、なぜ最初の
最初の
次の
pythonは行で説明されるため、コマンドはコードブロックです.
idleツールの各コマンドは独立したコードブロックですが、pyファイルは完全なコードブロックであり、関数、exec()などの他のコードブロックをネストすることもできます.したがって、上記の行賦値文がpyファイルに格納されている場合、結果はTrueになります.
例:
pythonはまず
同理
前文で複数回発生した異常をレビューします.
エラーメッセージ:
def文が実行されると、defは関数を宣言し、関数体はコードブロックであるため、このコードブロックに属する内容をコードブロックに従って読み出す.まず
でも下を見ると、どうしてまたTrueに戻ったの?
Pythonは起動時にメモリに通常の小さな整数値(-5~256)のオブジェクトを事前に作成しているため、非常に頻繁に使用されている(pythonの内部で使用されているものもある).したがって、この範囲内の整数は直接参照され、メモリに新しい数値オブジェクトは追加的に作成されないため、
前文ループ内の関数の問題を見てみましょう.
前述の現象について説明したように,内部関数n()におけるprint(i)のiはループの反復に伴って変化せず,固定値i=4である.
pythonはまず
同様に、
なお、関数の宣言中は、変数iに関連するすべての役割ドメイン内でiを付与することはなく、このi変数名が保存されているだけで、関数が呼び出されたときにのみ付与操作が行われる.
f 1()の呼び出しが開始されると、関数体のコードの実行が開始され、ループ反復が開始され、関数
f 1()()を呼び出すと、f 1()を呼び出すと返される関数n()が呼び出され、そのときになってn()内のiに値が付与され、値が付与されるとその外層関数f 1()の役割ドメインが検索され、この役割ドメイン内のiがメモリ内の数値4を指していることがわかり、最終出力4が出力される.
次のコードを見てください.
出力結果:
f 1()を呼び出すと、ループの反復が実行され、反復するたびにn()が呼び出され、反復するたびにn()のiが付与されることを意味する.
なお、前述したように、関数のデフォルトパラメータは、関数宣言時に付与されるので、以下のリストLの各要素が表す関数は、変数iが異なる数値オブジェクトを指す.
実行結果:
コードブロックは、pythonコードのセグメントを1つのユニットとして、全体として実行することができる.以下は公式マニュアルの説明です.
A Python program is constructed from code blocks. A block is a piece of Python program text that is executed as a unit. The following are blocks: a module, a function body, and a class definition. Each command typed interactively is a block. A script file (a file given as standard input to the interpreter or specified as a command line argument to the interpreter) is a code block. A script command (a command specified on the interpreter command line with the ‘-c’ option) is a code block. The string argument passed to the built-in functions eval() and exec() is a code block.
したがって、次のタイプのコードブロックがあります.
コードブロックの役割は、コードを組織することであり、コードブロック範囲を終了すると、役割ドメイン範囲を終了することを意味する.たとえば、関数ブロックを終了すると、関数の役割ドメインが終了し、関数内のローカル変数が関数の外部にアクセスできなくなります.
また、pythonは解釈言語で、1行を読んで1行を解釈します.これは、1行を読むたびに前の行を忘れることを意味します.しかし、実際には、より厳密には、1つのコードブロックを読んで1つのコードブロックを解釈することであり、これは、コードブロックの内容を読むときに、このコードブロックの中で読んだ内容に属していることを一時的に覚え、完全なコードブロックを読んでから、このコードブロックを統一的に解釈することを意味する.
まず、pythonのインタラクティブツールidleツールでのみテストできるコードブロックに属する行を読む場合について説明します.
>>> x=2000
>>> y=2000
>>> x is y
False
>>> x=2000;y=2000
>>> x is y
True
理論的にはセミコロンは文の区切り記号であり、結果には影響しません.しかし、なぜ最初の
x is y
がFalseで、2番目のx is y
がTrueなのか.最初の
x is y
を分析した.インタラクティブツールidleの各コマンドは個別の文ブロックであるため、x=2000
を説明するとすぐに2000という数値オブジェクトを忘れ、x変数自体も忘れてしまう.次に、説明y=2000
を読み出します.さっき説明したx=2000
を覚えていないので、メモリに2000という数値を保存するための数値構造を再作成し、yで指します.言い換えれば、xとyが指す2000はメモリ内で異なるデータオブジェクトであるため、x is y
はFalseである.次の
x is y
はTrueを返します.>>> x=2000;y=2000
>>> x is y
True
pythonは行で説明されるため、コマンドはコードブロックです.
x=2000;y=2000
の場合、pythonはまずこの行全体を読み出し、xとyの数値オブジェクトが2000であることを発見し、x,y=2000,2000
に等価な簡単な最適化を行います.これは、コードブロック内に属し、2000であるため、メモリにデータオブジェクトが作成され、xとyがこのデータオブジェクトを参照することを意味します.したがって、x is y
はTrueを返します.idleツールの各コマンドは独立したコードブロックですが、pyファイルは完全なコードブロックであり、関数、exec()などの他のコードブロックをネストすることもできます.したがって、上記の行賦値文がpyファイルに格納されている場合、結果はTrueになります.
例:
x = 2000
y = 2000
print(x is y) # True
def f1():
z=2000
z1=2000
print(x is z) # False
print(z is z1) # True
f1()
pythonはまず
x=2000
を読み出し、メモリにグローバル役割ドメインに属する2000データオブジェクトを作成し、y=2000を解釈すると、このグローバルオブジェクト2000はすでに存在していることに気づいた(xとyは同じグローバルコードブロック内にあるため)、新しい2000ペアは追加的に作成されない.ここで反映される結果は、「同じコードブロック内では、依然として1行の解釈1行を読むが、このコードブロックを終了する前に、このコードブロックの内容を忘れず、このコードブロックを統一的に手配する」ということである.同理
def f1()
内のコードブロックは、zがローカル役割ドメインの変数であり、より標準的には異なるコードブロック内にあるため、ローカル役割ドメインメモリ領域に新しいデータオブジェクト2000が作成されるため、x is z
はFalseを返す.前述の説明によれば、z1 is z
はTrueを返す.前文で複数回発生した異常をレビューします.
x = 3
def f1():
print(x)
x=4
f1()
エラーメッセージ:
UnboundLocalError: local variable 'x' referenced before assignment
def文が実行されると、defは関数を宣言し、関数体はコードブロックであるため、このコードブロックに属する内容をコードブロックに従って読み出す.まず
print(x)
を読みますが、直接説明するのではなく、それを覚えて下に読み続け、x=4を読みます.これは、xがローカル変数であることを意味します.次に、コードブロック全体を統一的に配置し、print(x)のxをグローバル変数ではなくローカル変数と見なす.なお、defが終了するまでxの付与は行われず、ローカル変数xが記録され、付与操作は関数呼び出し時に行われる.関数f()を呼び出すとprint(x)のxはローカル変数であるが、まだ値が付与されていないため、エラーが報告される.でも下を見ると、どうしてまたTrueに戻ったの?
>>> x=256
>>> y=256
>>> x is y
True
Pythonは起動時にメモリに通常の小さな整数値(-5~256)のオブジェクトを事前に作成しているため、非常に頻繁に使用されている(pythonの内部で使用されているものもある).したがって、この範囲内の整数は直接参照され、メモリに新しい数値オブジェクトは追加的に作成されないため、
x is y
は常にtrueを返します.さらに、これらの小さな整数は、役割ドメインにまたがることができます.x = 3
def f1():
y=3
print(x is y) # True
f1()
前文ループ内の関数の問題を見てみましょう.
def f1():
for i in range(5):
def n():
print(i)
return n
f1()()
前述の現象について説明したように,内部関数n()におけるprint(i)のiはループの反復に伴って変化せず,固定値i=4である.
pythonはまず
def f1()
のコードブロックを説明し、このコードブロックの役割ドメイン内に属する変数iおよびnを記録するが、iおよびnは値を付与しない.すなわち、変数nが関数変数であることは一時的に知られていない.同様に、
def n()
コードブロックを解釈する必要がある場合、このコードブロックに関連する変数iは、この変数iが外層関数に属するにすぎないが、いずれにしても、このコードブロックはiを記憶し、外部関数の役割ドメインであることを記憶する.なお、関数の宣言中は、変数iに関連するすべての役割ドメイン内でiを付与することはなく、このi変数名が保存されているだけで、関数が呼び出されたときにのみ付与操作が行われる.
f 1()の呼び出しが開始されると、関数体のコードの実行が開始され、ループ反復が開始され、関数
n()
が複数回宣言され、反復のたびに生成されたn()は、元に記録された変数nをこの新しい宣言された関数体(付与された動作に相当し、変数nが参照するオブジェクトは、一般的なデータオブジェクトではなく、関数体構造であるにすぎない)に指し示す.ループで関数n()を宣言するだけで呼び出しは行われないため、n()のiには値付け操作は行われません.また、ループ反復のたびに変数nが新しい関数体を指し、以前の反復中に定義された関数が破棄(上書き)されるため、最終的には最後のループ時に宣言された関数n()のみが記憶され、i=4となる.f 1()()を呼び出すと、f 1()を呼び出すと返される関数n()が呼び出され、そのときになってn()内のiに値が付与され、値が付与されるとその外層関数f 1()の役割ドメインが検索され、この役割ドメイン内のiがメモリ内の数値4を指していることがわかり、最終出力4が出力される.
次のコードを見てください.
def f1():
for i in range(5):
def n():
print(i)
n()
return n
f1()
出力結果:
0
1
2
3
4
f 1()を呼び出すと、ループの反復が実行され、反復するたびにn()が呼び出され、反復するたびにn()のiが付与されることを意味する.
なお、前述したように、関数のデフォルトパラメータは、関数宣言時に付与されるので、以下のリストLの各要素が表す関数は、変数iが異なる数値オブジェクトを指す.
def f1():
L = []
for i in range(5):
def n(i=i):
print(i)
L.append(n)
return L
f1()[0]()
f1()[1]()
f1()[2]()
f1()[3]()
f1()[4]()
実行結果:
0
1
2
3
4