Python
1x = 10 2a = x 3b = x 4x = 1 5print (a) 6print (b) 7print (x)
数字については例外なくすべて実値渡しでしょうか?
Python
1x = [1,2] 2a = x 3b = x 4x = [1,2,1] 5print (a) 6print (b) 7print (x) 8print () 9 10x = [1,2] 11a = x 12b = x 13x.append(1) 14print (a) 15print (b) 16print (x)
配列についてはどちらも同じ結果になると思ったのですが、実際には配列渡しになったり参照渡しとなりxが勝手に変更されたりよくわからない挙動をします。
どういったときにどのような挙動をするのか使いこなせるようになるには、どのように勉強すればいいでしょうか?
参照渡しになったり実値渡しになったりする言語は初めてでかなり戸惑っています。
宜しくお願い致します。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/10/11 13:58
2020/10/11 14:03
2020/10/11 14:28
2020/10/11 14:32
2024/04/10 06:36
回答4件
0
参照渡しになったり実値渡しになったりする言語は初めてでかなり戸惑っています。
Pythonに参照渡しは存在しません。
前提として、Python では引数は代入によって渡されます。代入はオブジェクトへの参照を作るだけなので、呼び出し元と呼び出し先にある引数名の間にエイリアスはありませんし、参照渡しそれ自体はありません。
また、そもそも代入を○○渡しと呼ぶこともありません。
変数への代入が、他の変数に影響することはありません。
####リストの場合
Python
1>>> a = [1] 2>>> b = a 3>>> print(a, b) 4[1] [1] 5>>> a = [2] 6>>> print(a, b) 7[2] [1]
####数値の場合
Python
1>>> a = 1 2>>> b = a 3>>> print(a, b) 41 1 5>>> a = 2 6>>> print(a, b) 72 1
変数の参照先への操作は、同じオブジェクトを参照している他の変数にも影響します。
####リストの場合
Python
1>>> a = [1] 2>>> b = a 3>>> print(a, b) 4[1] [1] 5>>> a.append(2) 6>>> print(a, b) 7[1, 2] [1, 2]
####数値の場合
Pythonの数値はイミュータブルなので、直接書き換える方法が存在しません。
これはオブジェクトの保持の仕方とは全く関係ありません。
他の言語では?
参照渡しになったり実値渡しになったりする言語は初めてでかなり戸惑っています。
過去質問を見る限り、JavaScriptとPerlのご経験があるようですね。
JavaScript
1var x = [1,2]; 2var a = x; 3var b = x; 4var x = [1,2,1]; 5console.log(a); // [ 1, 2 ] 6console.log(b); // [ 1, 2 ] 7console.log(x); // [ 1, 2, 1 ] 8console.log(); 9 10var x = [1,2]; 11var a = x; 12var b = x; 13x.push(1); 14console.log(a); // [ 1, 2, 1 ] 15console.log(b); // [ 1, 2, 1 ] 16console.log(x); // [ 1, 2, 1 ] 17console.log();
Perl
1$x = [1, 2]; 2$a = $x; 3$b = $x; 4$x = [1, 2, 1]; 5print "@$a\n"; # 1 2 6print "@$b\n"; # 1 2 7print "@$x\n"; # 1 2 1 8print "\n"; 9 10$x = [1, 2]; 11$a = $x; 12$b = $x; 13push @$x, 1; 14print "@$a\n"; # 1 2 1 15print "@$b\n"; # 1 2 1 16print "@$x\n"; # 1 2 1 17print "\n";
JavaScriptはあまり詳しくないですし、
Perlに至ってはさっきまでHello Worldすら書いたことがありませんでした。
変な間違いをしていたらすみません。
投稿2020/10/11 12:13
編集2020/10/11 13:34総合スコア35668
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/10/11 13:52
2020/10/11 14:03 編集
2020/10/11 14:11 編集
2020/10/11 14:25
2020/10/11 23:52
2020/10/12 09:14
2020/10/12 11:31
0
「再代入」と「破壊的変更」を、きちんと区別しましょう。
- 再代入…「変数に何が入っているか」というつながりを変更する
- 破壊的変更…「変数に何が入っているか」はそのままだけど、入っているものの方を加工する
「3」という整数の性質を変えることが想定できないように、数値の場合は変更はすべて再代入によります。一方で、x.append(1)
とするのは、入っているリストそのものを変更する破壊的変更の操作です。
投稿2020/10/11 12:12
総合スコア146018
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
(落ち穂拾い的回答です。maisumakunさんの回答に賛成ですが、"変数に入っている"という表現に違和感があったのでそこの指摘といった感じです)
質問者さんが本当に理解できてない急所的なポイントは、実は「代入文とはなにか? 変数とは何か?」だと感じました。
Pythonはここに癖がある言語だと思います。
https://docs.python.org/ja/3/reference/simple_stmts.html#assignment-statements
代入文は、名前を値に (再) 束縛したり、変更可能なオブジェクトの属性や要素を変更したりするために使われます
代入文は
- 名前を値に (再) 束縛する
- 変更可能なオブジェクトの属性や要素を変更する
ものだと明記されています。代入文の説明に"変数"や"代入"という用語が出てこないことは象徴的です。
"代入文"という言語要素はあるくせにその機能に"変数への代入操作"がありません。
言語仕様のページに"変数"という項目がないことも象徴的です。
実のところ、Pythonの実行モデルには変数がありません。
あるのは"名前づけと束縛"なのです。
https://docs.python.org/ja/3/reference/executionmodel.html#naming-and-binding
名前 (name) は、オブジェクトを参照します。名前を導入するには、名前への束縛 (name binding) 操作を行います。
(略)
ある名前がブロック内で束縛されているなら、 nonlocal や global として宣言されていない限り、それはそのブロックのローカル変数 (local variable) です。 ある名前がモジュールレベルで束縛されているなら、その名前はグローバル変数 (global variable) です。
この辺りの表現、"名前はオブジェクトを参照します。ある名前がブロック内で束縛されているなら、その名前はそのブロックのローカル変数です"といった文が腑に落ちるとよいだろうなと思いました。
あと、質問本体に関して確認/検索するべき用語はミュータブル/イミュータブルです(変更可能/変更不能or不変 とも言いますが、検索しやすさからミュータブル/イミュータブルを好んで使うプログラマが多いはず)。
https://docs.python.org/ja/3/glossary.html#term-mutable
ミュータブルなオブジェクトは、 id() を変えることなく値を変更できます。
https://docs.python.org/ja/3/glossary.html#term-immutable
固定の値を持ったオブジェクトです。イミュータブルなオブジェクトには、数値、文字列、およびタプルなどがあります。これらのオブジェクトは値を変えられません。別の値を記憶させる際には、新たなオブジェクトを作成しなければなりません。
https://docs.python.org/ja/3/reference/datamodel.html#index-15
このあたりでしょう。
生成したあとに中身を変えられるオブジェクトか、中身を変えられないオブジェクトか? という違いがあるという話です。
すでに複数の指摘は出ていますが、値渡しと参照渡しは関数の呼び出し時に引数をどうやって評価するか? ということに関する用語で、かつPythonには値渡ししかありません。
値渡しと参照渡しの違いは、言語仕様に値渡しと参照渡しの両方を含む言語を勉強するのが早いのでしょう。
投稿2020/10/11 23:48
編集2020/10/11 23:50総合スコア11235
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
投稿2020/10/11 13:24
総合スコア979
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/10/11 13:41 編集
2020/10/11 14:06
2020/10/11 14:09
2020/10/11 14:18
2020/10/11 14:20
2020/10/11 14:23
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。