web-dev-qa-db-ja.com

Python変数参照の割り当て

コード内

y = 7
x = y    
x = 8

これで、yは7になり、xは8になります。しかし、実際にはyを変更したいです。 yの参照を割り当てて実行できますか?

たとえば、C++では、同じことを達成できます。

int y = 8;
int &x = y;
x = 9;

これでyとxの両方が9になります

39
viji

いいえ、あなたがすることはできません。他の答えが指摘するように、可変オブジェクトのエイリアスを使用して(ab?)同様の効果を実現できます。ただし、これはC++の参照とは異なり、誤解を避けるために実際に何が起こるかを説明します。

C++(および他の言語)では、変数(およびオブジェクトフィールド、コレクション内のエントリなど)は格納場所であり、値(たとえば、整数、オブジェクト、またはポインター)を書き込むその場所。このモデルでは、参照は(任意の種類の)格納場所のエイリアスです。非参照変数に割り当てると、値が(単なるポインタであっても値のまま)格納場所にコピーされます。参照に割り当てると、別の場所にある保存場所にコピーします。参照自体は変更できないことに注意してください-一度バインドされると(作成するとすぐに)、参照へのすべての割り当てが参照ではなく、参照されるものを変更します。

Python(および他の言語)では、変数(およびオブジェクトフィールド、コレクション内のエントリなど)は単なる名前です。値はどこか else(例えば、ヒープ全体に散らばっています)、変数は値を参照します(C++参照という意味ではなく、ポインターからポインター演算を引いたようなものです)。 。Python(および他の言語)は、値を参照するために必要なものはすべて、C++参照や参照渡しのようなものとはまったく関係なく、参照を呼び出します。オブジェクトフィールド、または...)単純に別の値を参照します。格納場所のモデル全体はPythonには適用されず、プログラマは値の格納場所を処理することはありません。格納およびシャッフルはすべてPython参照。これらはPythonの値ではないため、他のPython参照。

これらはすべて、値の可変性とは無関係です。たとえば、intやリストでも同じです。いずれかを参照する変数を使用して、それが指すオブジェクトを上書きすることはできません。オブジェクトにそれ自体の一部を変更するように指示することしかできません。たとえば、含まれている参照を変更することです。

これはより制限的なモデルですか?おそらく、しかしほとんどの場合それは十分に強力です。そうでない場合は、以下に示すようなカスタムクラスを使用するか、(同等ではあるがそれほど明白ではない)単一要素コレクションを使用して回避できます。

_class Reference:
    def __init__(self, val):
        self._value = val # just refers to val, no copy

    def get(self):
        return self._value

    def set(self, val):
        self._value = val
_

それでも、「通常の」変数またはオブジェクトフィールドのエイリアスを作成することはできませんが、同じReferenceオブジェクトを参照する複数の変数を持つことができます(mutable-singleton-collectionの代替についても同じです)。常に.get()/.set()(または_[0]_)を使用するように注意する必要があります。

53
user395760

いいえ、Pythonにはこの機能がありません。

リスト(または他の可変オブジェクト)がある場合、xとyの両方がバインドされているオブジェクトを変更することで、必要な処理を実行できます。

>>> x = [7]
>>> y = x
>>> y[0] = 8
>>> print x
[8]

オンラインでの動作をご覧ください: ideone

16
Mark Byers

これには可変オブジェクトを使用する必要があります。

In python xyはオブジェクトへの単なる参照であるため、y = 7はyがオブジェクトを指す7x=yx7を指しますが、7は不変であるため、xの値を変更するとオブジェクトが変更されるだけです7y still 7を指し続けます。

>>> y = [7]
>>> x = y
>>> x[0] = 8 # here you're changing [7] not x or y, x & y are just references to [7]
>>> y
[8]
5

または、自作のコンテナを使用することもできます。

class Value(object):
    def __init__(self, value): self.value = value

y = Value(7)
x = y
x.value = 8
print y.value

ideone

3
glglgl