編集:私は非常に申し訳ないOP - 記述子を使用する私の提案は良いアイデアのように思えたが、堅牢な方法でmyA.m2.reset()
のようなコードを書くことができますするつもりされていません。
私はあなたのアイデアを提供するために、この回答を参考にしておきます。
これはpython descriptorsの仕事です!それはメンバーの(Iは緩くその言葉を使う)
myA.some_member.reset()
...とどのような「種類」に応じて、カスタム動作を持っている:私は理解していれば
は、あなたがこのような何かを行うことができるようにしたいです。
class ResettableDict(dict):
def reset(self):
self.clear()
class A(object):
def __init__(self):
self.m2 = ResettableDict()
あなたに実行しようとしている問題は、しかし、文字列は不変であるので、あなたは、str
をサブクラス化することにより、同様の何かを行うことができないということである(すなわち:あなたは、この辞書のようなm2
メンバーにうまく働いて得ることができます彼らはdict
のように "クリア"することはできません)。さらに、代入演算子を使用してResettableString
メンバーに値を渡すと、ResettableString
になります。例:
class ResettableString(str):
pass # Just a placeholder for this example
がテスト:
>>> myA = A()
>>> myA.m2[1] = 2
>>> type(myA.m2)
<class '__main__.ResettableDict'> # works!
>>> myA.m1 = 'string!'
>>> type(myA.m2)
<class 'str'> # no longer a ResettableString! DOH!!!
Pythonはほとんどの演算子を "オーバーロード" する機能があります。しかし、一般的に=
(代入)演算子にオーバーロードするクラスを書くことはできません。何をすべきか?
答え:私が最初に言ったように、記述子!我々はResettable
と呼ばれる記述子を作るつもりです。 Resettable
は、reset()
メソッドを使用して、メンバーの値をデフォルト値に戻します。
あなたはこのようにそれを使用します:ここで
class A(object):
m1 = Resettable('m1', None)
m2 = Resettable('m2', {})
はResettable
次のとおりです。
class Resettable(object):
'''A class descriptor that can be reset to its default value.'''
def __init__(self, name, default):
self.default = default
def reset(self):
setattr(self.current_instance, self.name, self.default)
del self.current_instance
def __get__(self, obj, typ):
try:
return getattr(obj, '_%s' % self.name)
except AttributeError:
setattr(obj, self.name, self.default)
return self.default
finally:
self.current_instance = obj
def __set__(self, obj, value):
setattr(obj, '_%s' % self.name, value)
A Pythonの記述は、多くの機能を提供します。それらのうちの1つは、=
(代入)演算子(__set__
メソッド経由、このメソッドはオプトイナイン)と.
( "get")演算子(__get__
メソッド経由)の両方の「オーバーロード」です。
オブジェクトメンバーに値を割り当てると、デフォルトのPythonのgetおよびsetの動作は、ディスクリプタオブジェクトによって提供される動作によって上書きされます。
>>> myA = A()
>>> myA.m2[1] = 2
>>> type(A.m2)
<class '__main__.Resettable'> # works!
>>> myA.m1 = 'string!'
>>> type(A.m1)
<class '__main__.Resettable'> # works!!!!!
>>> myA.m2.reset()
>>> myA.m1.reset()
このページを指摘していただきありがとうございます。しかし、m1/m2は、インスタンスmyAがクラスAではないことを意図しています。 –
@ Lazysheep.wang記述子がクラス 'A'オブジェクトメンバであり、インスタンスmyAオブジェクトメンバではないことは事実です。しかし、[descriptor protocol](http://python-reference.readthedocs.io/en/latest/docs/dunderdsc/)は、インスタンスメンバルックアップが開始されると、クラスレベルのメンバ記述子が存在する場合にそれが返されることを意味します。 –
リックありがとうございます。それは素晴らしい解決策です。実際には、このAクラスで少なくとも10人のメンバーを定義し、さらに追加していくことがあります。私は明日あなたのソリューションに自分のソリューションを組み込み、それに対応してこのスレッドを更新しようとします。そのような詳細であなたのソリューションをお寄せいただきありがとうございます! –