特定のプロパティが設定されるたびにカスタム エスケープを実行する方法と、それらのプロパティがオブジェクトの 1 つから取得されたときに対応するエスケープ解除コードを実行する方法を探しています。__setattr__、__getattr__、および __getattribute__ を見てきましたが、プロパティとの関係がわかりません。
たとえば、次のようなクラスがあります。
class Bundle(object):
def __init__(self):
self.storage = Storage()
@property
def users_name(self):
"""
Get the user's name
"""
return self.storage.users_name
@users_name.setter
def users_name(self, users_name):
"""
Set the user's name
"""
# only permit letters and spaces.
if not re.match('^[A-Za-z ]+$', users_name):
msg = "'%s' is not a valid users_name. It must only contain letters and spaces" % users_name
log.fatal(msg)
raise ConfigurationError(msg)
self.storage.users_name = users_name
...
オブジェクトには、そのようなプロパティがいくつかあります。
私が欲しいのは、一部のプロパティ (users_name など、「storage」など) にのみ影響し、設定/取得時に値をエスケープ/エスケープ解除するメソッドです。
- __getattr__ は、このコードが新規および既存のプロパティに対して呼び出される必要があるため、正しくないようです。
- __setattr__ は機能するかもしれませんが、@property メソッドにどのように適合するかわかりません。たとえば、__setattr__ はカスタム メソッドの代わりに常に呼び出されますか? __setattr__ 内からカスタム メソッドを呼び出すにはどうすればよいですか? 作業するプロパティのリストを保存せずに @property プロパティのみに影響を与える簡単な方法はありますか?
- __getattribute__ これを使ってみたのですが、無限ループになってしまいました。それはさておき、私の質問は __setattr__ とほぼ同じです @property で宣言されたメソッドに委譲することが可能かどうか (およびその方法は?)、および「プロパティだけではなく、これらのプロパティに対してのみ機能する」と言うのが最善の方法ですこのクラスの。
これにアプローチする最良の方法は何ですか?
- アップデート -
詳しく説明すると、この特定の 'Bundle' クラスはプロキシとして機能し、さまざまなバックエンド (この場合は ConfigParser をラップする FileConfigBackend) に構成値を格納します。ConfigParser は補間に「%」記号を使用します。ただし、設定したい値の一部には正当にパーセント記号が含まれている可能性があるため、それらをエスケープする必要があります。ただし、プロパティごとに明示的にエスケープするのではなく、プロパティが設定されるたびに呼び出されるある種の魔法のメソッドが必要です。次に、文字列で実行replace('%', '%%')
されます。同様に、プロパティが取得されるたびreplace('%%', '%')
に、値を返す前に値に対して実行されるメソッドが必要です。
また、「Bundle」内のプロパティの大部分は単純にバックエンド ストレージにプロキシされるため、「プロパティがこのリストにある場合は呼び出すだけ」という方法があればいいと思いますself.storage.PROPERTY_NAME = VALUE
。たとえば、設定する値に対して正規表現を実行するなど、その割り当てをオーバーライドできるようにしたい場合もあります。
本当に、「プロパティが設定されているときは、常にこのメソッドを呼び出す」という方法を探しています。次に、具体的な @property.setter が存在する場合は、self.storage.key = value
'.
(doh! 私は __getattr__ & __setattr__ ではなく __get__ と __set__ を意味していました - それを反映するために私の質問を更新しました)