リストのようなコレクション、Pythonの別の関数に配列を渡すとき、それはコピーを作成しますか、それとも単なるポインタですか?
Python 値への参照をオブジェクトに渡します 。
Pythonはオブジェクトへの参照を値(Javaなど)で渡し、Pythonのすべてがオブジェクトです。これは単純に聞こえますが、一部のデータ型はパスバイを示すように見えることに気付くでしょう-値の特性、他の人は参照渡しのように動作するように見えますが...取引は何ですか?
可変および不変オブジェクトを理解することが重要です。文字列、タプル、数値などの一部のオブジェクトは不変です。関数/メソッド内で変更すると、新しいインスタンスが作成され、関数/メソッド外の元のインスタンスは変更されません。リストや辞書などの他のオブジェクトは可変です。つまり、オブジェクトをその場で変更できます。したがって、関数/メソッド内のオブジェクトを変更すると、元のオブジェクトも外部に変更されます。
つまり、参照/値の概念全体がpythonに適合しません。 Pythonには変数の「値」がありません。Pythonにはオブジェクトとオブジェクトを参照する名前のみがあります。
したがって、関数を呼び出して、次のように括弧内に「名前」を入れると:
def func(x): # defines a function that takes an argument
... # do something here
func(myname) # calling the function
namemyname
itselfではなく、myname
が指している実際のオブジェクトが渡されます。関数内では別の名前(x
)が渡され、同じオブジェクトを参照します。
関数内のオブジェクトは変更可能であれば変更できますが、外部名が指しているものは変更できませんです。あなたがするときに起こることと同じ
anothername = myname
したがって、私はあなたの質問に答えることができます:
「値渡し」ですが、すべての値はオブジェクトへの単なる参照です。
ここでの回答は役に立ちましたが、これまで見たことのないこのすばらしい区別を示す必要性があります。これについては、後続のCL実験で証明しました。
「num」は不変のNumberオブジェクトであるため、ここでは変更されません[私のポイント1をサポートします]:
def incr_num(num):
num += 1
num = 0
num
0
incr_num(num)
num
0
ここでの 'list [0]'は不変のNumberオブジェクトでもあります。
def incr_list(list):
list[0] += 1
list = [0]
list[0]
0
incr_list(list)
list[0]
1
では、不変のNumberオブジェクトである「list [0]」はどのように変更されましたか(私のポイント2をサポート)、上記の例のNumberオブジェクト「num」は変更されませんでしたか?不変のNumberオブジェクト'list [0]'は可変リストオブジェクト 'list'に含まれますが、最初の例の 'num'は単なる非連結のNumberオブジェクトです。
よく意図されていますが、私は @ Stephen Pape 最高評価の回答(以下に引用)、および他のいくつかの同様の回答が完全に正しくなかったと感じています(そして、それがこの回答を書く動機になりました):
文字列、タプル、数値などの一部のオブジェクトは不変です。関数/メソッド内で変更すると、新しいインスタンスが作成され、関数/メソッド外の元のインスタンスは変更されません。
上記の2回目のコード実験では、Numberオブジェクト( 'list [0]')がメソッド内で変更され、その後関数外の元のインスタンスが変更されたことが示されています。
参照は渡されますが、パラメーターが不変オブジェクトである場合、メソッド内でパラメーターを変更すると新しいインスタンスが作成されます。
オブジェクトが渡されます。コピーではなく、基礎となるオブジェクトへの参照。
参照により:
>>> x = [0,1,2,3]
>>> def foo(x_list):
x_list[0] = 1
>>> foo(x)
>>> x
[1, 1, 2, 3]
謙虚な例を挙げてください
def swap(a, b):
x = a
print id(x)
print id(a)
print id(b)
a = b
print id(a)
b = x
print id(b)
a[0]= '20'
var1 = ['1','2','3','4']
var2 = ['5','6','7','8','9']
print id(var1)
print id(var2)
swap(var1, var2)
print id(var1)
print id(var2)
print var1
print var2
次の結果が生成されます
28329344 var1 28331264 var2 28329344 x 28329344 a 28331264 b a = bの後28331264 a b = x 28329344 bの後復帰後28329344 var1 28331264 var2 ['1'、 '2'、 '3'、 '4'] ['20'、 「6」、「7」、「8」、「9」]
メモリアドレスへのマッピング28329344 28331264 var1 var2 abx a = baの後b = xbの後a [0] = '20' [0] = '20'戻り後['1'、 '2'、 '3'、 ' 4 '] [' 20 '、' 6 '、' 7 '、' 8 '、' 9 ']