pythonってポインタ渡しみたいなことできないんですか?
解決済
回答 4
投稿
- 評価
- クリップ 5
- VIEW 5,648
関数の引数で関数の外の値を変えたいんですけどできないんですか?
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
+7
上から順にお勧めです。
- 戻り値で結果を返すようにする
気軽に複数の要素を返せますし、Cと違ってうっかりフルコピーしてしまうことがないです。 - ミュータブルな要素を引数として渡す
状況によってはこちらが自然です。 - グローバル宣言をして再代入
個人的には禁忌だと思います。『Python global』で調べてください。
なお、
pythonってポインタ渡しみたいなことできないんですか?
もともと全部ポインタ渡しみたいなもんです。
参照値を関数内部で書き換えたときに呼び出し元に影響しないのはCも一緒。
#include <stdio.h>
int the_answer = 42;
void func(int* arg) {
arg = &the_answer;
printf("%d\n", *arg); // 42
}
int main(void) {
int var = -1;
func(&var);
printf("%d\n", var); // -1
return 0;
}
def func(arg):
arg = 42
print(arg) # 42
var = -1
func(var)
print(var) # -1
私が『参照渡し』に期待する動作
#include<iostream>
void func(int& arg) {
arg = 42;
std::cout << arg << std::endl; // 42
}
int main(void) {
int val = -1;
func(val);
std::cout << val << std::endl; // 42
return 0;
}
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
checkベストアンサー
+6
追記: 本件からちょっと外れてしまうかもしれませんが、下手に「値渡し」と書いてしまいお馴染みの混乱を招く結果になってしまったようです。
call by value
call by reference
call by sharing
という用語を使うとするとcall by sharingが一番しっくりきそうに思います。(hayataka2049さんありがとうございます)。pythonだけでなくjavaとかC#(の参照型)とか多くの言語でもお馴染みの評価戦略だと思います。call by valueとずっと捉えてたのですがその用語を使うのは控えてcall by sharingといおうと思いました。
以下の元の回答
参照渡しはできません。常に値渡しです。
変更した値を何らかの変更可能なコンポーネントオブジェクト(listとかdictとか)の要素にしておいて、関数の中でコンポーネントオブジェクトの要素を変更するようにすればまぁポインター渡しっぽいことができなくはないです。
ちなみに固定的な変数なのであれば
- グローバル変数ならglobal宣言を用いればできます。
- 外側のローカル変数でもnonlocalを使うとそれができる場面があります。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
+3
もう質問クローズしてますが、余談として。
Pythonのような言語では、参照渡しの存在を気にする必要がないと感じています。
値渡しだけで事が足りてしまうという意味で。
def update_a_b_c(a, b, c):
a = a * something1
b = b + something2
c = c / something3
return (a, b, c)
something はなんかしらの何かなので気にしないでください。
上記のようにreturnで複数の要素を返却できるので、引数経由で値を返す必要がありません。
a, b, c = update_a_b_c(a, b, c)
受け取り先で上記のように受け取れば、a, b, cをそれぞれ更新できます。
議論からは逸れていますが、考える必要のないものを考えるのも時間がもったいない、と思いまして一筆取った次第。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
+2
むしろ逆で、デフォルトでポインタ渡しみたいになっています。それどころか、変数もすべてポインタで実体と結びついていますし。
>>> lst = []
>>> def append_lst(lst):
... lst.append(None)
...
>>> lst
[]
>>> append_lst(lst)
>>> lst
[None]
でもこっちは失敗します。
>>>a = 1
>>>def add_a(a):
... a = a + 1
...
>>>a
1
>>>add_a(a)
>>>a
1
add_aはローカル変数aのポインタが「1」オブジェクトから「2」オブジェクトに張り替えられて終了するだけ。「1」オブジェクトの実体に影響したりはしません。
一応、リストに入れればそれっぽいことはできます。
>>> a = 1
>>> lst = [a]
>>> def add_a2(lst):
... lst[0] = lst[0] + 1
...
>>> lst
[1]
>>> add_a2(lst)
>>> lst
[2]
これは「1」オブジェクトにポインタを張ってるリストを渡して、そのポインタを「2」に張り替える操作をしたんです。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 90.36%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる