7

次のコードを機能させる方法があるかどうかのアイデア

class Test(object):

    def __init__(self, var):
        self.var = var

    def changeme(self):
        self = Test(3)

t = Test(1)
assert t.var == 1
t.changeme()
assert t.var == 3

より複雑なオブジェクト(djangoモデルなど、インスタンスが参照しているdbエントリをホットスワップするため)に安全に使用できる次のようなものです。

class Test(object):

    def __init__(self, var):
        self.var = var

    def changeme(self):
        new_instance = Test(3)
        self.__dict__ = new_instance.__dict__

t = Test(1)
assert t.var == 1
t.changeme()
assert t.var == 3
4

3 に答える 3

7

self = Test(3)はローカル名を再バインドしますがself、外部から観察できる影響はありません。

割り当て(重要なメタクラスを持つクラスのself.__dict__インスタンスまたはクラスからのインスタンスについて話している場合を除く)は通常は問題ありません。そのため、インスタンスを再初期化する必要があります。ただし、すでに初期化されたインスタンスで呼び出されていることを認識し、その特定の異常なケースに対応するために必要なことをすべて実行する特定のメソッドが必要です。__slots__self.__init__(3)self.restart(3)

于 2010-01-26T06:20:31.540 に答える
2

いいえ、いいえ。

そうは言っても、クラスを変更することはできますが、そうしないでください。

于 2010-01-26T06:16:32.133 に答える
2

前者のコードは、changeme()のスコープ内で「self」という名前のオブジェクトを置き換えるだけなので、あまり機能しないことを除いて、機能します。Python名は値にロックされておらず、常にスコープまたは名前空間に相対的です。

やりたいことを行うには、クラス外の名前にアクセスする必要があります。この名前には、クラス内から割り当てることができます。

class Test:
  def changeme(self):
    global myclass
    myclass = Test(3)

myclass = Test(2)
myclass.changeme()
print myclass # 3

これは基本的に、名前'myclass'を上書きして、新しいインスタンスを指すようにします。あなたが思うかもしれないように、それは最初のインスタンスを「上書き」しません。古いインスタンスはまだ存続しており、他の場所で参照されない限り、ガベージコレクションされます。

于 2010-01-26T06:20:08.960 に答える