a = [1,2,3]
def foo(b):
b.append(4)
foo(a)
print(a) # [1,2,3,4]
def bar(c):
c = [0,0,0]
bar(a)
print(a) # [1,2,3,4]
値渡しまたは参照渡しと言われているので、C ++について話す必要があります(私が知る限り、これらの概念はPythonにはありません)。主題と読者はC ++についてある程度の知識があることを前提としています。まず、実際のパラメーターと仮パラメーターの概念を確認します。foo関数を見てください。これがc ++関数であると仮定すると、foo(a)を呼び出すプロセスで、aが実際のパラメーター、bが仮パラメーターです。この概念について曖昧な場合は、cをよく見てください。++ primerでの関数パラメータ転送の部分の内容はここでは繰り返されません。値による受け渡しと参照による受け渡しを見てみましょう。
- 値の受け渡しとは、実際のパラメーターの値を値として仮パラメーターにコピーすることであり、関数内の仮パラメーターの操作は、実際のパラメーターとは関係ありません。これは、明らかにパラメーターを渡す方法ではありません。 python。foo関数を見てください。値が渡されると、bは[1,2,3]のコピーをコピーし、b.append(4)を実行すると、[1,2,3,4]になります。 ]ですが、bの変更はaには影響しません。実際、aも変更されています。
- 参照渡しでは、仮パラメーターを使用して実際のパラメーターにエイリアスを指定します。関数内の仮パラメーターの操作は、実際には実際のパラメーターの操作です。C++での参照渡しの例を示します。
//命名空间和头文件此处省略了
void test(vector<int>& vi)
{
vi = vector<int>{ 0,0,0 };
}
int main()
{
vector<int> v{ 1,1,1 };
test(v); // 因为是传引用,执行结束后 v 变成了vector<int>{ 0,0,0 }
return 0;
}
Pythonは参照によるものではないことがわかります。ここで、bar関数とtest関数を比較してください。bar(a)を実行した後、aは[0,0,0]ではなく、aは変更されていないため、答え。可変オブジェクトが参照によるものであると言うのは間違っていると思います。
したがって、値でも参照でもありません!Python関数にパラメータを渡す方法を理解するには、Pythonの「名前バインディング」を理解することが不可欠です。私は自分の言葉を使ってより簡潔に説明しようとしています。詳細については、リンクを参照してください。最後に。未定義のものxxを使用すると、PythonはNameErrorを報告するため、これらのものを変数ではなく名前としてa、b、foo、barと呼びます。名前「xx」は定義されていません。Pythonでは、nameには型がなく、nameでポイントされるオブジェクトには型があります。たとえば、name aはオブジェクトint番号1を指すことも、リストオブジェクトを指すようにすることもできます。次のコードについて考えてみます。
x = 1
y = x
print(y is x) #True 注意此处的is用来比较 y 与 x 所指向的对象是否为同一个,也就是id(x)与id(y)是不是一样的
# id方法返回的是某对象的id号(一个int值),在其生命周期内保证唯一和不变, id(x)就是返回x所指向的对象的id
y = 2
print(y is x) # False
x += 1 # 此时x的值为2, x绑定到了对象 int2 上,同时id(x)也会发生改变
print(y is x) # True
x = 1は、オブジェクトint 1がxという名前(名前)でバインド(ビンビン)されていることを意味し、名前xを使用してint1オブジェクトを参照できます。また、y = xは、yがオブジェクトint 1の名前でもあり、名前yを使用してオブジェクトint1を参照できることを意味します。また、yとxは同じオブジェクトの名前であるため、y isxはTrueを返します。名前xとyは異なるオブジェクトを指しているため、y = 2、yはxはFalseです。x + = 1、この時点で、id(x)が変更され、返されるidはオブジェクトint2のIDであることに注意してください。次に、y is xを再度実行すると、すべてオブジェクトint 2を指しているため、Trueが返されます。