2011-11-18 11 views
6

は、なぜこのようなケースではありません、私は入力は今10をだろうと思っ私はPythonがすべてを渡したと思った?

#module functions.py 
def foo(input, new_val): 
    input = new_val 

#module main.py 
input = 5 
functions.foo(input, 10) 

print input 

次のコードを取りますか?

+0

関数fooの定義でローカル変数 "input"を呼び出すと、混乱することがあります。また、Svenが答えで言ったこと。 – phkahler

+6

あなたが読んだところでは、Pythonはすべてを参照渡しますが、間違っていました。 –

答えて

13

すべてが値渡しですが、その値は元のオブジェクトへの参照です。オブジェクトを変更すると、変更が呼び出し側に表示されますが、名前を再割り当てすることはできません。さらに、多くのオブジェクトは不変(ints、float、strings、tuples)です。

+8

"[熟語Python](http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html#other-languages-have-variables)では、この現象をよく説明しています。 –

+1

Pythonはcall-by-valueやcall-by-referenceではありません。 –

+1

@skyhisi:あなたの答えは本質的に私と同じですが、非標準的な用語である "オブジェクトによる呼び出し"を使用する点を除き、私は意図的に避けています。なぜなら、anythinを説明していないからです。 –

8

fooの内部で、ローカル名inputを別のオブジェクト(10)にバインドしています。呼び出しコンテキストでは、inputという名前は、依然として5オブジェクトを参照しています。

5

Pythonでの割り当ては、インプレースオブジェクトを変更しません。それはinput = new_valの後にローカル変数inputが新しい値を得るように名前を再バインドします。

あなたはinput「外」を変更したい場合、あなたはこのような1要素のリストとして可変オブジェクトの内部でそれをラップする必要があります:

def foo(input, new_val): 
    input[0] = new_val 

foo([input]) 

Pythonは参照渡しかしません正確にC++のリファレンス渡しが動作する方法。この場合、すべての引数は、C/C++でのポインタであるかのように、少なくとも、それはより多くのです:

// effectively a no-op! 
void foo(object *input, object *new_val) 
{ 
    input = new_val; 
} 
+0

皆様のお返事ありがとうございます...あなたが提案したこの方法は、ほとんどの場合ハックのようですが、この標準的な手順ですか?より多くのpythonの不変型を変更する他の方法はありますか? (私は '不変型の変更は自分自身の質問に答えると思いますが、とにかく質問します...) – Ferguzz

+0

@Ferguzz定義によって不変なオブジェクトを変更することはできません。しかし、それは本当にあなたが頼んでいたものですか?今のところ、不変オブジェクトは言及されていません。 'var = ...'がオブジェクトやその他の変数を変更しないという事実は、不変性とは何の関係もありません。あるリストを変更して別のリストに影響を与えることができないように、1つの変数代入を別の変数に変更することはできません。 – delnan

+0

私はこの回答の行を 'リストのような変更可能なオブジェクトの中にラップする'ことを指していました。私は尋ねようとしていました、私の元の投稿のように変数を変更する方法はありませんか? – Ferguzz

3

Pythonはどちらもコールバイ値であり、またはお電話・バイ・リファレンス、それがCall By Objectです。

「引数は同様の引数はオブジェクト であり、彼らが可変である場合にのみ変更することができることを除くコールバイ値、 に、コール・バイ・共有によって渡されます。」

+1

素敵な要約ですが、依然としてcall-by-objectはcall-by-value以外のもので、すべての "値"はオブジェクトに対するハンドル(〜=ポインタ)です。 – Kos

関連する問題