8

どこでもpythonオブジェクトを別のオブジェクトに置き換えるにはどうすればよいですか?

私は2つのクラスを持っていSimpleObjectますFancyObject. を作成しSimpleObject、それへの参照をいくつか持っています。を作成しFancyObject、これらすべての参照が新しいオブジェクトを指すようにします。

a = SimpleObject()
some_list.append(a)
b = FancyObject()

a = bは私が望むものではなく、 a が指すものを変更するだけです。以下はうまくいくと読んだが、うまくいかない。「属性 __dict__ は書き込み可能ではありません」というエラーが表示されます。

a.__dict__ = b.__dict__

私が欲しいのは(疑似C)と同等です:

*a = *b

私はこれがハックであることを知っていますが、これを達成する方法はありますか?

4

5 に答える 5

2

そのオブジェクトを別のモジュールのグローバル名前空間に配置し、必要に応じてモンキー パッチを適用できます。

objstore.py:

replaceable = object()

sample.py:

import objstore

b = object()

def isB():
     return objstore.replaceable is b

if __name__ == '__main__':
     print isB()#False
     objstore.replaceable = b
     print isB()#True

PS モンキーパッチに頼るのは悪い設計の兆候です

于 2013-07-26T09:18:33.030 に答える
1

方法はありません。不変オブジェクトを変更して、あらゆる種類の不快感を引き起こす可能性があります。

x = 1
y = (x,)
z = {x: 3}
magic_replace(x, [1])
# x is now a list!
# The contents of y have changed, and z now has an unhashable key.

x = 1 + 1
# Is x 2, or [1, 1], or something stranger?
于 2013-07-26T08:46:24.457 に答える
0

いくつかのオプションがあります:

  1. Facade パターン (つまり、メイン コード内のすべてのオブジェクトが別のオブジェクトのプロキシ) を使用するか、単一の変更可能なコンテナー (つまり、すべての変数がリストを保持します。リストの内容は、そのような参照)。利点は、言語の実行機構で動作し、影響を受けるコードから比較的簡単に発見できることです。欠点: コードが増える。
  2. 常に同じ単一変数を参照してください。これは上記の実装の 1 つです。クリーンで、派手なものはなく、コードが明確です。私はこれを断然お勧めします。
  3. デバッグ、gc、およびイントロスペクション機能を使用して、基準を満たすすべてのオブジェクトを探し出し、実行中に変数を変更します。欠点は、コードの実行中に変数の値が変更され、影響を受けるコードから検出できないことです。変更がアトミック (エラーのクラスを排除する) であっても、値が異なる型であると判断したコードの実行後に変数の型が変更される可能性があるため、そのコードで合理的に予測できないエラーが発生します。例えば

    a = iter(b) # will blow up if not iterable
    [x for x in b] # before change, was iterable, but between two lines, b was changed to an int.
    

さらに巧妙に言えば、文字列シーケンスと非文字列シーケンスを区別する場合 (文字列を定義する特徴は、文字列を反復すると文字列も生成され、それ自体が反復可能であるため)、構造を平坦化するときにコードが壊れる可能性があることです。

別の回答では、オプション 3 を実装するpyjackについて言及されています。動作する可能性がありますが、言及されているすべての問題があります。これは、デバッグと開発でのみ適切である可能性があります。

于 2013-08-14T14:46:28.420 に答える
0

リストなどの変更可能なオブジェクトを利用します。

a = [SimpleObject()]
some_list.append(a)
b = FancyObject()
a[0] = b

これが機能することの証明:

class SimpleObject():
    def Who(self):
        print 'SimpleObject'

class FancyObject():
    def Who(self):
        print 'FancyObject'

>>> a = [SimpleObject()]
>>> a[0].Who()
SimpleObject
>>> some_list = []
>>> some_list.append(a)
>>> some_list[0][0].Who()
SimpleObject
>>> b = FancyObject()
>>> b.Who()
FancyObject
>>> a[0] = b
>>> some_list[0][0].Who()
FancyObject
于 2013-08-14T14:51:08.990 に答える