3045

パラメータが参照または値によって渡されるかどうかについて、Python のドキュメントは不明確なようであり、次のコードは変更されていない値 'Original' を生成します。

class PassByReference:
    def __init__(self):
        self.variable = 'Original'
        self.change(self.variable)
        print(self.variable)

    def change(self, var):
        var = 'Changed'

実際の参照によって変数を渡すためにできることはありますか?

4

35 に答える 35

3261

引数は代入によって渡されます。これには次の 2 つの理由があります。

  1. 渡されたパラメーターは、実際にはオブジェクトへの参照です (ただし、参照は値によって渡されます)
  2. 一部のデータ型は可変ですが、他の型はそうではありません

そう:

  • 変更可能なオブジェクトをメソッドに渡すと、メソッドは同じオブジェクトへの参照を取得し、それを喜んで変更できますが、メソッドで参照を再バインドすると、外側のスコープはそれについて何も知りません。これで、外部参照は元のオブジェクトを指したままになります。

  • 不変オブジェクトをメソッドに渡した場合でも、外部参照を再バインドすることはできず、オブジェクトを変更することさえできません。

さらに明確にするために、いくつかの例を挙げてみましょう。

リスト - 変更可能な型

メソッドに渡されたリストを変更してみましょう。

def try_to_change_list_contents(the_list):
    print('got', the_list)
    the_list.append('four')
    print('changed to', the_list)

outer_list = ['one', 'two', 'three']

print('before, outer_list =', outer_list)
try_to_change_list_contents(outer_list)
print('after, outer_list =', outer_list)

出力:

before, outer_list = ['one', 'two', 'three']
got ['one', 'two', 'three']
changed to ['one', 'two', 'three', 'four']
after, outer_list = ['one', 'two', 'three', 'four']

渡されたパラメータは への参照outer_listであり、そのコピーではないため、変更リスト メソッドを使用してパラメータを変更し、その変更を外側のスコープに反映させることができます。

パラメータとして渡された参照を変更しようとするとどうなるか見てみましょう。

def try_to_change_list_reference(the_list):
    print('got', the_list)
    the_list = ['and', 'we', 'can', 'not', 'lie']
    print('set to', the_list)

outer_list = ['we', 'like', 'proper', 'English']

print('before, outer_list =', outer_list)
try_to_change_list_reference(outer_list)
print('after, outer_list =', outer_list)

出力:

before, outer_list = ['we', 'like', 'proper', 'English']
got ['we', 'like', 'proper', 'English']
set to ['and', 'we', 'can', 'not', 'lie']
after, outer_list = ['we', 'like', 'proper', 'English']

the_listパラメータは値で渡されたため、新しいリストを割り当てても、メソッドの外側のコードからは何の影響もありませんでした。は参照the_listのコピーであり、新しいリストを指していましたが、指している場所を変更する方法がありませんでした。outer_listthe_listouter_list

String - 不変型

不変なので、文字列の内容を変更するためにできることは何もありません

では、参照を変更してみましょう

def try_to_change_string_reference(the_string):
    print('got', the_string)
    the_string = 'In a kingdom by the sea'
    print('set to', the_string)

outer_string = 'It was many and many a year ago'

print('before, outer_string =', outer_string)
try_to_change_string_reference(outer_string)
print('after, outer_string =', outer_string)

出力:

before, outer_string = It was many and many a year ago
got It was many and many a year ago
set to In a kingdom by the sea
after, outer_string = It was many and many a year ago

繰り返しになりますが、the_stringパラメーターは値で渡されたため、新しい文字列を割り当てても、メソッドの外部のコードからは何の影響もありませんでした。は参照the_stringのコピーであり、新しい文字列を指していましたが、指している場所を変更する方法がありませんでした。outer_stringthe_stringouter_string

これで問題が少し解決することを願っています。

編集:これは、@ David が最初に尋ねた質問「実際の参照で変数を渡すためにできることはありますか?」に答えていないことに注意してください。それに取り組みましょう。

どうすればこれを回避できますか?

@Andreaの答えが示すように、新しい値を返すことができます。これは、物事が渡される方法を変更しませんが、必要な情報を取り戻すことができます:

def return_a_whole_new_string(the_string):
    new_string = something_to_do_with_the_old_string(the_string)
    return new_string

# then you could call it like
my_string = return_a_whole_new_string(my_string)

本当に戻り値の使用を避けたい場合は、クラスを作成して値を保持し、それを関数に渡すか、リストなどの既存のクラスを使用できます。

def use_a_wrapper_to_simulate_pass_by_reference(stuff_to_change):
    new_string = something_to_do_with_the_old_string(stuff_to_change[0])
    stuff_to_change[0] = new_string

# then you could call it like
wrapper = [my_string]
use_a_wrapper_to_simulate_pass_by_reference(wrapper)

do_something_with(wrapper[0])

これは少し面倒に思えますが。

于 2009-06-12T11:18:27.077 に答える
810

この問題は、Python の変数とは何かを誤解していることが原因です。ほとんどの伝統的な言語に慣れている場合は、次の順序で何が起こるかのメンタル モデルがあります。

a = 1
a = 2

aあなたはそれが値を格納するメモリの場所であると信じており、値を格納1するために更新されます2。これは、Python での動作ではありません。むしろ、a値 を持つオブジェクトへの参照として開始され、値 を持つオブジェクトへの1参照として再割り当てされます2aこれらの 2 つのオブジェクトは、最初のオブジェクトを参照しなくなっても共存し続ける可能性があります。実際、それらはプログラム内の任意の数の他の参照によって共有される場合があります。

パラメータを指定して関数を呼び出すと、渡されたオブジェクトを参照する新しい参照が作成されます。これは、関数呼び出しで使用された参照とは別のものであるため、その参照を更新して、新しいオブジェクト。あなたの例では:

def __init__(self):
    self.variable = 'Original'
    self.Change(self.variable)

def Change(self, var):
    var = 'Changed'

self.variable文字列オブジェクトへの参照'Original'です。呼び出すと、オブジェクトへのChange2 番目の参照が作成varされます。関数内で参照varを別の文字列オブジェクト'Changed'に再割り当てしますが、参照self.variableは別のものであり、変更されません。

これを回避する唯一の方法は、可変オブジェクトを渡すことです。両方の参照が同じオブジェクトを参照するため、オブジェクトへの変更は両方の場所に反映されます。

def __init__(self):         
    self.variable = ['Original']
    self.Change(self.variable)

def Change(self, var):
    var[0] = 'Changed'
于 2011-11-15T17:45:28.460 に答える
413

他の回答はかなり長く複雑であることがわかったので、Python が変数とパラメーターを処理する方法を説明するために、この簡単な図を作成しました。 ここに画像の説明を入力

于 2014-09-04T16:05:35.447 に答える
263

これは、値渡しでも参照渡しでもありません。オブジェクトごとの呼び出しです。FredrikLundhによるこれを参照してください。

http://effbot.org/zone/call-by-object.htm

ここに重要な引用があります:

「...変数[名前]はオブジェクトではありません。他の変数で示したり、オブジェクトで参照したりすることはできません。」

あなたの例では、Changeメソッドが呼び出されると、名前空間が作成されます。そしてvar、その名前空間内で、文字列オブジェクトの名前になります'Original'。そのオブジェクトは、2つの名前空間に名前が付けられます。次に、新しい文字列オブジェクトにvar = 'Changed'バインドvarするため、メソッドの名前空間は。を忘れます'Original'。最後に、その名前空間'Changed'とそれに伴う文字列が忘れられます。

于 2009-06-12T12:55:41.773 に答える
207

参照/値ではなく、割り当てによって渡されるものを考えてください。そうすれば、通常の割り当て中に何が起こるかを理解している限り、何が起こっているかが常に明確になります。

そのため、リストを関数/メソッドに渡すと、リストがパラメーター名に割り当てられます。リストに追加すると、リストが変更されます。関数内でリストを再割り当てしても、元のリストは変更されません。

a = [1, 2, 3]
b = a
b.append(4)
b = ['a', 'b']
print a, b      # prints [1, 2, 3, 4] ['a', 'b']

不変型は変更できないため、値渡しのように見えます。関数に int を渡すということは、関数のパラメーターに int を割り当てることを意味します。それを再割り当てすることしかできませんが、元の変数の値は変更されません。

于 2009-06-12T12:17:48.777 に答える
89

Pythonには変数がありません

パラメータの受け渡しを理解する鍵は、「変数」について考えるのをやめることです。Python には名前とオブジェクトがあり、それらは一緒に変数のように見えますが、常に 3 つを区別すると便利です。

  1. Python には名前とオブジェクトがあります。
  2. 割り当ては、名前をオブジェクトにバインドします。
  3. 関数に引数を渡すと、名前 (関数のパラメーター名) もオブジェクトにバインドされます。

それだけです。可変性は、この質問には関係ありません。

例:

a = 1

aこれにより、値 1 を保持する整数型のオブジェクトに名前がバインドされます。

b = x

これにより、名前が現在バインドされてbいるのと同じオブジェクトに名前がバインドされます。xその後、その名前はもはやb名前とは何の関係もありxません。

Python 3 言語リファレンスのセクション3.14.2を参照してください。

質問の例の読み方

質問に示されているコードでは、ステートメントは名前( function のスコープ内) を値を保持するオブジェクトにself.Change(self.variable)バインドし、代入( function の本体内) は同じ名前を再度割り当てます: 他のオブジェクトに (それが起こります)文字列を保持することもできますが、まったく別のものになる可能性があります)。varChange'Original'var = 'Changed'Change

参照渡しの方法

したがって、変更したいものが変更可能なオブジェクトである場合、すべてが事実上参照によって渡されるため、問題はありません。

不変オブジェクト (bool、数値、文字列など) の場合、変更可能なオブジェクトでラップする方法があります。
これに対する手っ取り早い解決策は、1 つの要素のリストです (関数の中でself.variable, pass[self.variable]および modify を使用する代わりにvar[0])。
よりPythonicなアプローチは、単純な 1 つの属性クラスを導入することです。関数はクラスのインスタンスを受け取り、属性を操作します。

于 2014-02-11T11:29:07.127 に答える
82

Effbot (別名 Fredrik Lundh) は、Python の変数受け渡しスタイルをオブジェクトごとの呼び出しと説明しています: http://effbot.org/zone/call-by-object.htm

オブジェクトはヒープに割り当てられ、それらへのポインターはどこにでも渡すことができます。

  • などの割り当てを行うx = 1000と、現在の名前空間の文字列 "x" を 1000 を含む整数オブジェクトへのポインターにマップする辞書エントリが作成されます。

  • "x" を で更新するとx = 2000、新しい整数オブジェクトが作成され、新しいオブジェクトを指すように辞書が更新されます。古い 1,000 個のオブジェクトは変更されていません (オブジェクトを参照するオブジェクトが他にあるかどうかによって、生きている場合もあれば、生きていない場合もあります)。

  • などの新しい割り当てを行うと、y = x「x」のエントリと同じオブジェクトを指す新しい辞書エントリ「y」が作成されます。

  • 文字列や整数などのオブジェクトは不変です。これは単に、作成後にオブジェクトを変更できるメソッドがないことを意味します。たとえば、整数オブジェクト 1000 が作成されると、それは決して変更されません。数学は、新しい整数オブジェクトを作成することによって行われます。

  • リストのようなオブジェクトは変更可能です。これは、オブジェクトを指すものによってオブジェクトの内容を変更できることを意味します。たとえば、x = []; y = x; x.append(10); print yを出力します[10]。空のリストが作成されました。「x」と「y」はどちらも同じリストを指しています。appendメソッドはリスト オブジェクトを変更 (更新) し (レコードをデータベースに追加するのと同じように)、結果は "x" と "y" の両方に表示されます (データベースの更新がそのデータベースへのすべての接続に表示されるように)。

問題が明確になることを願っています。

于 2013-03-29T04:41:44.097 に答える
63

技術的には、Python は常に参照値による受け渡しを使用します。私の声明を裏付けるために、他の回答を繰り返します。

Python は常に参照渡しの値を使用します。例外はありません。変数の割り当ては、参照値をコピーすることを意味します。例外なし。任意の変数は、参照値にバインドされた名前です。いつも。

参照値は、対象オブジェクトのアドレスと考えることができます。アドレスは、使用時に自動的に逆参照されます。このように、参照値を操作すると、ターゲット オブジェクトを直接操作しているように見えます。しかし、その間には常に参照があり、ターゲットにジャンプするためにさらに一歩進んでいます。

Python が参照渡しを使用していることを証明する例を次に示します。

引数を渡す例

引数が値で渡された場合、外側lstを変更できませんでした。緑はターゲット オブジェクト (黒は内部に格納された値、赤はオブジェクト タイプ)、黄色は内部に参照値を持つメモリです。矢印として描かれています。青い実線の矢印は、(破線の青い矢印のパスを介して) 関数に渡された参照値です。醜い濃い黄色は内部辞書です。(実際には緑色の楕円としても描くことができます。色と形は内部としか言いようがありません。)

組み込み関数を使用しid()て、参照値が何であるか (つまり、対象オブジェクトのアドレス) を知ることができます。

コンパイルされた言語では、変数は型の値をキャプチャできるメモリ空間です。Python では、変数は、ターゲット オブジェクトへの参照値を保持する参照変数にバインドされた名前 (文字列として内部的に取得される) です。変数の名前は内部ディクショナリのキーであり、そのディクショナリ項目の値の部分にはターゲットへの参照値が格納されます。

参照値は Python では隠されています。参照値を格納するための明示的なユーザー タイプはありません。ただし、リスト要素 (または他の適切なコンテナー タイプの要素) を参照変数として使用できます。これは、すべてのコンテナーが要素をターゲット オブジェクトへの参照としても格納するためです。つまり、要素は実際にはコンテナー内に含まれていません。要素への参照のみがコンテナー内に含まれています。

于 2012-09-15T18:53:57.520 に答える
55

私が通常使用する簡単なトリックは、リストでラップすることです。

def Change(self, var):
    var[0] = 'Changed'

variable = ['Original']
self.Change(variable)      
print variable[0]

(ええ、これは不便かもしれませんが、これを行うのに十分簡単な場合もあります。)

于 2011-08-05T22:52:00.413 に答える
39

(編集 - ブレアは非常に人気のある回答を更新して、正確になりました)

最も多くの票を獲得した現在の投稿 (ブレア・コンラッドによる) は、結果に関しては正しいものの、誤解を招きやすく、その定義に基づいて境界線上で不正確であることに注意することが重要だと思います。ユーザーが参照渡しまたは値渡しを許可する言語 (C など) は多数ありますが、Python はその 1 つではありません。

David Cournapeau の回答は本当の回答を示しており、Blair Conrad の投稿の動作が正しいように見えるのに、定義が正しくない理由を説明しています。

Python が値渡しである限り、一部のデータ (「値」または「参照」) を送信する必要があるため、すべての言語は値渡しです。ただし、これは、C プログラマーが考えるような意味で Python が値渡しであるという意味ではありません。

動作が必要な場合は、ブレア コンラッドの答えで問題ありません。しかし、Python が値渡しでも参照渡しでもない理由の要点を知りたい場合は、David Cournapeau の回答をお読みください。

于 2010-06-27T12:33:45.930 に答える
28

あなたはここでいくつかの本当に良い答えを得ました.

x = [ 2, 4, 4, 5, 5 ]
print x  # 2, 4, 4, 5, 5

def go( li ) :
  li = [ 5, 6, 7, 8 ]  # re-assigning what li POINTS TO, does not
  # change the value of the ORIGINAL variable x

go( x ) 
print x  # 2, 4, 4, 5, 5  [ STILL! ]


raw_input( 'press any key to continue' )
于 2009-06-12T12:16:45.860 に答える
22

この場合、varメソッドでタイトルが付けられた変数Changeに への参照が割り当てられ、self.variableすぐに文字列を に割り当てますvar。を指していませんself.variablevar次のコード スニペットは、とが指すデータ構造self.variable(この場合はリスト)を変更するとどうなるかを示しています。

>>> class PassByReference:
...     def __init__(self):
...         self.variable = ['Original']
...         self.change(self.variable)
...         print self.variable
...         
...     def change(self, var):
...         var.append('Changed')
... 
>>> q = PassByReference()
['Original', 'Changed']
>>> 

他の誰かがこれをさらに明確にすることができると確信しています。

于 2009-06-12T10:39:59.370 に答える
22

Python の割り当て渡し方式は、C++ の参照パラメーター オプションとまったく同じではありませんが、実際には C 言語 (およびその他) の引数渡しモデルと非常に似ていることがわかります。

  • 不変の引数は効果的に「<strong>値渡し」で渡されます。整数や文字列などのオブジェクトは、コピーではなくオブジェクト参照によって渡されますが、不変オブジェクトはその場で変更できないため、その効果はコピーを作成するのとほとんど同じです。
  • 変更可能な引数は、事実上「<strong>ポインターによって」渡されます。リストやディクショナリなどのオブジェクトもオブジェクト参照によって渡されます。これは、C が配列をポインタとして渡す方法と似ています。変更可能なオブジェクトは、C 配列と同じように関数内で変更できます。
于 2015-03-27T04:38:18.580 に答える
19

あなたが言うことができるように、可変オブジェクトが必要ですが、グローバル変数をチェックすることをお勧めします.

http://docs.python.org/3/faq/programming.html#what-are-the-rules-for-local-and-global-variables-in-python

例:

>>> def x(y):
...     global z
...     z = y
...

>>> x
<function x at 0x00000000020E1730>
>>> y
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'y' is not defined
>>> z
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'z' is not defined

>>> x(2)
>>> x
<function x at 0x00000000020E1730>
>>> y
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'y' is not defined
>>> z
2
于 2014-02-10T17:57:39.790 に答える
18

ここでの回答には多くの洞察がありますが、ここでは追加の点が明確に言及されていないと思います。Python ドキュメントからの引用https://docs.python.org/2/faq/programming.html#what-are-the-rules-for-local-and-global-variables-in-python

「Python では、関数内でのみ参照される変数は暗黙的にグローバルです。変数が関数本体内のどこかに新しい値を割り当てられた場合、それはローカルであると見なされます。変数が関数内で新しい値を割り当てられた場合、変数は暗黙的にローカルであり、それを明示的に「グローバル」として宣言する必要があります.最初は少し驚くかもしれませんが、少し考えてみるとこれが説明されます.一方で、割り当てられた変数にグローバルを要求すると、意図しない副作用に対するバーが提供されます.一方、すべてのグローバル参照にグローバルが必要な場合は、常にグローバルを使用することになり、組み込み関数またはインポートされたモジュールのコンポーネントへのすべての参照をグローバルとして宣言する必要があります。副作用を特定するためのグローバル宣言の有用性を無効にします。」

変更可能なオブジェクトを関数に渡す場合でも、これは適用されます。そして、オブジェクトへの割り当てと関数内のオブジェクトの操作との間の動作の違いの理由を明確に説明します。

def test(l):
    print "Received", l , id(l)
    l = [0, 0, 0]
    print "Changed to", l, id(l)  # New local object created, breaking link to global l

l= [1,2,3]
print "Original", l, id(l)
test(l)
print "After", l, id(l)

与えます:

Original [1, 2, 3] 4454645632
Received [1, 2, 3] 4454645632
Changed to [0, 0, 0] 4474591928
After [1, 2, 3] 4454645632

したがって、グローバルと宣言されていないグローバル変数への代入は、新しいローカル オブジェクトを作成し、元のオブジェクトへのリンクを解除します。

于 2014-09-12T14:40:18.670 に答える
10

これが Python でどのように機能するかについての素晴らしい説明を除けば、この問題に対する単純な提案は見当たりません。オブジェクトとインスタンスを作成しているように見えるので、インスタンス変数を処理してそれらを変更する Pythonic の方法は次のとおりです。

class PassByReference:
    def __init__(self):
        self.variable = 'Original'
        self.Change()
        print self.variable

    def Change(self):
        self.variable = 'Changed'

インスタンス メソッドでは、通常、selfインスタンス属性にアクセスするために参照します。インスタンス属性を設定__init__し、インスタンス メソッドで読み取りまたは変更するのが普通です。selfこれが、 の最初の引数として alsを渡す理由でもありますdef Change

別の解決策は、次のような静的メソッドを作成することです。

class PassByReference:
    def __init__(self):
        self.variable = 'Original'
        self.variable = PassByReference.Change(self.variable)
        print self.variable

    @staticmethod
    def Change(var):
        var = 'Changed'
        return var
于 2016-02-07T23:18:36.587 に答える
9

次の方法を使用して、いくつかの Fortran コードを Python にすばやく変換しました。確かに、元の質問が提起されたので参照渡しではありませんが、場合によっては簡単な回避策です。

a=0
b=0
c=0
def myfunc(a,b,c):
    a=1
    b=2
    c=3
    return a,b,c

a,b,c = myfunc(a,b,c)
print a,b,c
于 2016-08-08T16:46:05.160 に答える
8

オブジェクトを参照渡しするちょっとしたコツがありますが、言語ではそれが可能ではありません。Java でも動作します。1 つの項目を持つリストです。;-)

class PassByReference:
    def __init__(self, name):
        self.name = name

def changeRef(ref):
    ref[0] = PassByReference('Michael')

obj = PassByReference('Peter')
print obj.name

p = [obj] # A pointer to obj! ;-)
changeRef(p)

print p[0].name # p->name

これは醜いハックですが、機能します。;-P

于 2016-04-21T16:47:42.057 に答える
5

Python が値とそれらへの参照を処理する方法を考えると、任意のインスタンス属性を参照できる唯一の方法は名前です。

class PassByReferenceIsh:
    def __init__(self):
        self.variable = 'Original'
        self.change('variable')
        print self.variable

    def change(self, var):
        self.__dict__[var] = 'Changed'

もちろん、実際のコードでは、dict ルックアップにエラー チェックを追加します。

于 2016-10-31T15:33:23.517 に答える
4

あなたの例はたまたまオブジェクト指向であるため、次の変更を加えて同様の結果を得ることができます。

class PassByReference:
    def __init__(self):
        self.variable = 'Original'
        self.change('variable')
        print(self.variable)

    def change(self, var):
        setattr(self, var, 'Changed')

# o.variable will equal 'Changed'
o = PassByReference()
assert o.variable == 'Changed'
于 2017-09-10T02:19:53.650 に答える
4

ディクショナリは参照によって渡されるため、dict 変数を使用して、参照される値を内部に格納できます。

# returns the result of adding numbers `a` and `b`
def AddNumbers(a, b, ref): # using a dict for reference
    result = a + b
    ref['multi'] = a * b # reference the multi. ref['multi'] is number
    ref['msg'] = "The result: " + str(result) + " was nice!"
    return result

number1 = 5
number2 = 10
ref = {} # init a dict like that so it can save all the referenced values. this is because all dictionaries are passed by reference, while strings and numbers do not.

sum = AddNumbers(number1, number2, ref)
print("sum: ", sum)             # the returned value
print("multi: ", ref['multi'])  # a referenced value
print("msg: ", ref['msg'])      # a referenced value
于 2019-05-05T14:14:56.030 に答える
2

代わりに、ctypes witch を使用することもできます。次のようになります。

import ctypes

def f(a):
    a.value=2398 ## resign the value in a function

a = ctypes.c_int(0)
print("pre f", a)
f(a)
print("post f", a)

a は ac int であり、python 整数ではなく、明らかに参照渡しされているためです。ただし、奇妙なことが起こる可能性があるため、注意が必要です。

于 2021-01-28T11:06:18.840 に答える
1

おそらく最も信頼できる方法ではありませんが、これは機能します。組み込みの str 関数をオーバーロードしていることに注意してください。これは通常、やりたくないことです。

import builtins

class sstr(str):
    def __str__(self):
        if hasattr(self, 'changed'):
            return self.changed

        return self

    def change(self, value):
        self.changed = value

builtins.str = sstr

def change_the_value(val):
    val.change('After')

val = str('Before')
print (val)
change_the_value(val)
print (val)
于 2021-03-26T14:49:25.073 に答える
0

簡単な答え:

C++ のような Python では、オブジェクト インスタンスを作成してパラメーターとして渡すと、インスタンス自体のコピーは作成されないため、関数の外側と内側から同じインスタンスを参照し、オブジェクトのコンポーネント データムを変更できます。同じオブジェクト インスタンスであるため、変更が外部に表示されます。

基本型の場合、python と c++ も互いに同じように動作します。インスタンスのコピーが作成されるため、外部は関数の内部とは異なるインスタンスを認識/変更します。したがって、内側からの変化は外側には見えません。

Python と C++ の本当の違いは次のとおりです。

c++ にはアドレス ポインターの概念があり、c++ では代わりにポインターを渡すことができます。これにより、基本的な型のコピーがバイパスされます。これにより、関数の内部が外部のインスタンスと同じインスタンスに影響を与えることができるため、変更は関数にも表示されます。外側。これは Python に相当するものがないため、回避策 (ラッパー型の作成など) なしでは不可能です。

このようなポインターは Python では便利ですが、C++ ほど必要ではありません。C++ では単一のエンティティしか返せないのに対し、Python ではコンマで区切られた複数の値 (つまりタプル) を返すことができるからです。したがって、Python では、変数 a、b、および c があり、それらを (外部に対して) 永続的に変更する関数が必要な場合は、次のようにします。

a=4
b=3
c=8

a,b,c=somefunc(a,b,c)
# a,b,c now have different values here

このような構文は c++ では簡単に実現できないため、c++ では代わりに次のようにします。

int a=4
int b=3
int c=8
somefunc(&a,&b,&c)
// a,b,c now have different values here
于 2021-11-17T16:09:39.960 に答える