Pythonの変数、参照、および役割ドメイン
4219 ワード
Pythonの変数、参照、および役割ドメイン
可変オブジェクト&非可変オブジェクト
pythonでは、オブジェクトは可変オブジェクトと非可変オブジェクトの2つに分けられます.可変オブジェクトにはint,float,long,str,tupleなどがあり,可変オブジェクトにはlist,set,dictなどがある.ここでいう可変とは、値の可変を指す.可変タイプの変数の場合、変数を変更すると、新しい値が作成され、変数が新しい値にバインドされ、古い値が参照されずにゴミ回収が待機します.可変タイプのデータがオブジェクトに対して操作される場合、他の場所でメモリを申請する必要はありません.
変数にはタイプがなく、オブジェクトにはタイプがあります.
pythonでは、タイプは変数ではなくオブジェクトに属し、変数とオブジェクトは分離され、オブジェクトはメモリにデータが格納されているエンティティであり、変数はオブジェクトへのポインタである.
関数値の転送
第1の例は値を伝達し、第2の例は参照を伝達し、主に可変オブジェクトと可変オブジェクトのためである:可変オブジェクトの場合、オブジェクトの操作はオブジェクトを再構築しない;一方、可変オブジェクトでは、操作ごとにオブジェクトが再構築されます.
関数パラメータ伝達の過程でpythonは,実際にはパラメータに伝達された変数に対応するオブジェクトの参照を対応する関数内部変数に順次付与する.
上の例を参照して説明したほうが分かりやすい、func_intのローカル変数「a」は、実はグローバル変数t」が指すオブジェクトの別の参照であり、整数オブジェクトは可変であるためfunc_int変数「a」を修正すると,実際には局所変数「a」を整数オブジェクト「1」に指向する.だから明らかにfunc_Listが変更したのは可変オブジェクト、ローカル変数"a_listとグローバル変数t_list」は同じオブジェクトを指します.
アクティブドメイン pythonが変数の役割ドメインを変更できるコードセグメントはdef,class,lamda である. if/elif/else,try/except/finally,for/whileは変数の役割ドメインの変更を設計することはできません.つまり、彼らのコードブロック内の変数は、外部でもアクセスできます. 変数検索パスは、ローカル変数->グローバル変数 です.
例えば、Cでは、
if句は局所変数iを導入し,外部には見えない.したがって、printf関数で変数iを参照するとエラーが発生します.
しかしpythonではそうではありません.
このコードではif句にはローカル変数は導入されず、変数iは依然としてグローバル役割ドメインに存在するため、変数iは次のprint文に対して可視である.
pythonでは、変数を使用する前に事前に宣言する必要はありませんが、実際に使用する前に、オブジェクトにバインドされている必要があります.名前バインドは、現在の役割ドメインに新しい変数を導入し、外層役割ドメインの同じ名前の変数をマスクします.
出力結果は8と0であり,局所からグローバルへのプロセスである.
可変オブジェクト&非可変オブジェクト
pythonでは、オブジェクトは可変オブジェクトと非可変オブジェクトの2つに分けられます.可変オブジェクトにはint,float,long,str,tupleなどがあり,可変オブジェクトにはlist,set,dictなどがある.ここでいう可変とは、値の可変を指す.可変タイプの変数の場合、変数を変更すると、新しい値が作成され、変数が新しい値にバインドされ、古い値が参照されずにゴミ回収が待機します.可変タイプのデータがオブジェクトに対して操作される場合、他の場所でメモリを申請する必要はありません.
>>> a = 1
>>> id(a)
140320746581480
>>> id(1)
140320746581480
>>> a = 3
>>> id(3)
140320746581432
>>> id(a)
140320746581432
>>> b = 3
>>> id(b)
140320746581432
変数にはタイプがなく、オブジェクトにはタイプがあります.
pythonでは、タイプは変数ではなくオブジェクトに属し、変数とオブジェクトは分離され、オブジェクトはメモリにデータが格納されているエンティティであり、変数はオブジェクトへのポインタである.
関数値の転送
def func_int(a):
a += 4
def func_list(a_list):
a_list[0] = 4
t = 0
func_int(t)
print t
# output: 0
t_list = [1, 2, 3]
func_list(t_list)
print t_list
# output: [4, 2, 3]
第1の例は値を伝達し、第2の例は参照を伝達し、主に可変オブジェクトと可変オブジェクトのためである:可変オブジェクトの場合、オブジェクトの操作はオブジェクトを再構築しない;一方、可変オブジェクトでは、操作ごとにオブジェクトが再構築されます.
関数パラメータ伝達の過程でpythonは,実際にはパラメータに伝達された変数に対応するオブジェクトの参照を対応する関数内部変数に順次付与する.
上の例を参照して説明したほうが分かりやすい、func_intのローカル変数「a」は、実はグローバル変数t」が指すオブジェクトの別の参照であり、整数オブジェクトは可変であるためfunc_int変数「a」を修正すると,実際には局所変数「a」を整数オブジェクト「1」に指向する.だから明らかにfunc_Listが変更したのは可変オブジェクト、ローカル変数"a_listとグローバル変数t_list」は同じオブジェクトを指します.
アクティブドメイン
例えば、Cでは、
#include
int main() {
if(2 > 0) {
int i = 0;
}
printf("i = %d", i);
return 0;
}
if句は局所変数iを導入し,外部には見えない.したがって、printf関数で変数iを参照するとエラーが発生します.
しかしpythonではそうではありません.
if True:
i = 0
print i
このコードではif句にはローカル変数は導入されず、変数iは依然としてグローバル役割ドメインに存在するため、変数iは次のprint文に対して可視である.
pythonでは、変数を使用する前に事前に宣言する必要はありませんが、実際に使用する前に、オブジェクトにバインドされている必要があります.名前バインドは、現在の役割ドメインに新しい変数を導入し、外層役割ドメインの同じ名前の変数をマスクします.
i = 0
def f():
i = 8
print i
f()
print i
出力結果は8と0であり,局所からグローバルへのプロセスである.