Pythonで参照によって整数を渡すにはどうすればよいですか?
関数に渡す変数の値を変更したい。Pythonのすべてが値渡しであると読みましたが、簡単なトリックが必要です。たとえば、Javaでは、、などの参照型を渡すことができInteger
ますLong
。
- 参照によって整数を関数に渡すにはどうすればよいですか?
- ベストプラクティスは何ですか?
Pythonで参照によって整数を渡すにはどうすればよいですか?
関数に渡す変数の値を変更したい。Pythonのすべてが値渡しであると読みましたが、簡単なトリックが必要です。たとえば、Javaでは、、などの参照型を渡すことができInteger
ますLong
。
Pythonではそのようには機能しません。Pythonはオブジェクトへの参照を渡します。関数内にはオブジェクトがあります-(可能であれば)そのオブジェクトを自由に変更できます。ただし、整数は不変です。回避策の1つは、変更可能なコンテナーに整数を渡すことです。
def change(x):
x[0] = 3
x = [1]
change(x)
print x
これはせいぜい醜い/不器用ですが、Pythonでこれ以上うまくいくことはありません。その理由は、Pythonでは、代入(=
)が右側の結果であるオブジェクトを受け取り、それを左側にあるものにバインドするためです*(または適切な関数に渡します)。
これを理解すると、関数内の不変オブジェクトの値を変更する方法がない理由がわかります。不変であるため、その属性を変更することはできず、「変数」に新しいものを割り当てることはできません。これは、実際に新しいオブジェクト(古いオブジェクトとは異なる)を作成し、古いオブジェクトがローカル名前空間に持っていた名前を付けているためです。
通常、回避策は、必要なオブジェクトを返すことです。
def multiply_by_2(x):
return 2*x
x = 1
x = multiply_by_2(x)
*上記の最初の例では、3
実際にはに渡されx.__setitem__
ます。
参照渡しが必要になるほとんどの場合は、呼び出し元に複数の値を返す必要がある場合です。「ベスト プラクティス」は、複数の戻り値を使用することです。これは、Java などの言語よりも Python の方がはるかに簡単です。
簡単な例を次に示します。
def RectToPolar(x, y):
r = (x ** 2 + y ** 2) ** 0.5
theta = math.atan2(y, x)
return r, theta # return 2 things at once
r, theta = RectToPolar(3, 4) # assign 2 things at once
値を直接渡すのではなく、渡されたかのように使用します。
x = 7
def my_method():
nonlocal x
x += 1
my_method()
print(x) # 8
警告:
nonlocal
Python 3で導入されましたglobal
代わりに を使用しnonlocal
ます。実際、ベストプラクティスは、一歩下がって、本当にこれを行う必要があるかどうかを尋ねることです。関数に渡す変数の値を変更したいのはなぜですか?
簡単なハックのためにそれを行う必要がある場合、最も簡単な方法はlist
、整数を保持することを渡し、 [0]
mgilsonの答えが示すように、それを使用するたびにそれを回避することです。
より重要なことのためにそれを行う必要がある場合は、属性としてclass
を持っているを記述しint
てください。そうすれば、それを設定することができます。もちろん、これにより、クラスと属性の適切な名前を思い付く必要があります。何も考えられない場合は、戻って文を数回読み直してから、を使用してlist
ください。
より一般的には、JavaイディオムをPythonに直接移植しようとしている場合、それは間違っています。static
( /のように)直接対応するものがある@staticmethod
場合でも、Javaで使用するという理由だけで、ほとんどのPythonプログラムでそれを使用することは望ましくありません。
Python では、Java の非プリミティブと同様に、すべての値が参照 (オブジェクトへのポインター) です。また、Java と同様に、Python には値渡ししかありません。つまり、意味的にはほとんど同じです。
質問でJavaに言及しているので、Javaであなたが望むものをどのように達成するかを見たいと思います。Java でそれを示すことができれば、Python でまったく同じように行う方法を示すことができます。
class PassByReference:
def Change(self, var):
self.a = var
print(self.a)
s=PassByReference()
s.Change(5)
Pythonでは、すべてが値によって渡されますが、ある状態を変更する場合は、メソッドに渡されるリストまたはオブジェクト内の整数の値を変更できます。