Python はcall-by-objectと呼ばれることもあるシステムを使用します。関数に引数を渡すと、何もコピーされません。関数の引数の名前は、関数本体内で、関数呼び出しで提供された同じオブジェクトにローカルにバインドされます。
これは、オブジェクトをコピーしないため、ほとんどの人が「値による呼び出し」と考えるものとは異なります。しかし、参照はオブジェクトに対するものであるため、「参照による呼び出し」とも異なります--- 新しい名前がバインドされますが、同じオブジェクトにバインドされます。これは、渡されたオブジェクトを変更できることを意味しますが、関数内で名前を再バインドしても、関数の外では効果がありません。違いの簡単な例:
>>> def func(x):
... x[0] = 2 # Mutating the object affects the object outside the function
>>> myList = [1]
>>> func(myList)
>>> myList # myList has changed
[2]
>>> def func(x):
... x = 2 # rebinding name has no effect outside the function
>>> myList = [1]
>>> func(myList)
>>> myList # myList is unaffected
[1]
これについての私の単純な考え方は、裸の名前への割り当て、つまり形式のステートメントへの割り当ては、name = value
Python の他のすべてのものとはまったく異なるということです。値ではなく名前を操作する唯一の方法は、 do を実行することですname = value
。(これには、いじくり回すなどの細かい例外がありますが、globals()
とにかく危険な領域です。) 特に、 、、、および代入のように見えるが実際には名前ではなくオブジェクトを操作する他の同様のものとname = value
は異なります。obj.prop = value
obj[0] = value
obj += value
とはいえ、Python での関数呼び出しには、それ自体にある程度のオーバーヘッドがあります (実行フレームの設定など)。関数が何度も呼び出されると、このオーバーヘッドがパフォーマンスに顕著な影響を与える可能性があります。そのため、1 つの関数を複数に分割しても、追加の関数呼び出しごとにオーバーヘッドが追加されるため、パフォーマンスに影響を与える可能性があります。