Top page

Pythonの変数型 (上級者向)

・ pythonでは、変数、関数、クラス、変数型、ファイル (モジュール) まで、全てオブジェクトです

・ pythonの変数へのアクセスは、全て参照型です

・ 一般的な言語では、大きなサイズの変数を関数に渡すときは、ポインタあるいは参照型を渡します

・ pythonでは全ての変数は参照型ですが、整数型、浮動小数点型、論理型などの基本変数型は、関数内部で変更しても、元の変数に影響を与えません

関数内で基本変数型の引数への代入が関数の呼び出しもとに影響を与えないことは他の言語と同じですが (代入の副作用は同じ)、
pythonでは、python特有の仕様で実現しています。興味のある方は以下の説明を読んでください。

引数変数で渡された整数型などを関数内で変更する場合、例えば以下のようになります。

def func(i):
    i = 3
 
i = 5
print("1: i=", i)
 
func(i)
print("2: i=", i)
 
他の多くのプログラム言語と同様 (初期のBASICなどは例外です)、1:の i は 5 で、2: の i  も5 のままで、func()中での変更は反映されません。
これは、他のプログラム言語では関数への引数は値渡しをしているため、関数内の変数の実体は関数の呼び出し元の変数とは異なるためです。
一方、上記の通りpythonでは基本変数型を含めて全て参照の値渡しをしており、下記のように変数への代入では代入する変数・値の参照に置き換えることで
値を変えています。この機構により、関数内での値の変更は関数の呼び出しもとの値に影響を与えないようになっています。

 例えば、上記の i = 5 の i のアドレスを XXXX とします。
 func(i) 中での  i = 3 では、3 のアドレスを YYYY とすると、i のアドレスは YYYY に置き換わります。この i は、func(i)の局所変数です。
 func() の外部の i はfunc(i)の局所変数 i と別ですので、値は変わりません。

・ ミュータブルとイミュータブル

ただし、イミュータブルなオブジェクトのすべての内部の値を変更できないわけではありません。

タプルはイミュータブルなので

a = (1, 2, 3)
a[0] = 3

はエラーになりますが、

a = ([], [],. [])
a[0].append(3)

は問題ありません。変更できないのは タプル () の要素のアドレスです。


オブジェクトの例 (仮想コード)

 catオブジェクト: propertyとして、color, weight, methodとして move(), position()などが考えられる。

# クラスの定義 (概念的なプログラムリストなので以下のままでは動かない)

class cat():

      # pythonでは、 # 以降は行末までがコメント文として、無視される

      # 関数は def文で定義し、: で終わる

      # 変数は 変数名 = 初期値 とすることで、初期値を設定できる

def __init__(self, color = 'white', weight = 20.0):

color = color       # ややこしいけど注意。左のcolorcatattribute変数

# 右辺のcolor__init__関数の引数変数

            weight = weight

            x = 0.0             # 位置変数 x,y,z 0.0 で初期化しておく

            y = 0.0

            z = 0.0

        def move(dx, dy, dz):   # 位置をdx,dy,dzだけ移動させる

                …

 

        def position():

            return x, y, z  # 位置を [x,y,z]リストで返すメソッド

 

 インスタンスの生成(変数の作成)

  nyanko = cat()    # catクラスで定義されたオブジェクトのインスタンス変数nyankoをつくる。

                       # 引数を指定していないので、初期値が使われ、

              # naynako.color 'white'nyanko.weight 20kgになる。

  nyanko = cat(color = 'black')

                      # catクラスで定義されたオブジェクトのインスタンス変数nyankoをつくる。

                      # 引数で指定されたcolor変数は初期値から変更され、naynako.color 'black' になる

 

  nyanko.move(3, -1, 0)を実行すると、nyanko.x, nyanko.y, nyanko.zはそれぞれ 3, -1, 0 になる

  nyanko.move(-1, 3, 2)を実行すると、nyanko.x, nyanko.y, nyanko.zはそれぞれ 2, 2, 2 になる