あなた後者の例では、私のために動作しますが、あなたの主な問題は、あなたが
@catch_assertionerror
@name.setter
def name(self, value):
assert isinstance(value, str), "This value should be a string"
self._name = name
が、descriptor
にcatch_assertionerror
で関数をラップしていないことです。さらに悪いことに、関数を返すのではなく、元の記述子をラップする新しい記述子ではありません。今度はname
属性に代入すると、ラッパー関数を割り当てられた値に置き換えるだけです。ステップバイ
は
ステップ、元のクラス定義を使用して:
class X(object):
@property
def name(self):
return self._name
@catch_assertionerror
@name.setter
def name(self, value):
assert isinstance(value, str), "This value should be a string"
self._name = value
>>> x = X()
>>> x.name
<unbound method X.handle_problems>
>>> x.__dict__
{}
>>> x.name = 2
>>> x.name
2
>>> x.__dict__
{'name': 2}
何をしなければならないことは代わりにメソッドの機能をラップして、記述子取扱デコレータに渡しです:
class X(object):
@property
def name(self):
return self._name
@name.setter
@catch_assertionerror
def name(self, value):
assert isinstance(value, str), "This value should be a string"
self._name = value
ので、 :
>>> x = X()
>>> x.name
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in name
AttributeError: 'X' object has no attribute '_name'
>>> x.name = 2
error caught
>>> x.name = "asdf"
>>> x.name
'asdf'
今後はfunctools.wraps
とfunctools.update_wrapper
を使用することを検討してください。あなたのラッパーが非表示になりますので、それらがなければ、あなたのクラスと関数は、検査することが困難です元:
>>> @catch_assertionerror
... def this_name_should_show(): pass
...
>>> this_name_should_show
<function handle_problems at 0x7fd3d69e22a8>
あなたのデコレータこの方法の定義:
>>> @catch_assertionerror
... def this_name_should_show(): pass
...
>>> this_name_should_show
<function this_name_should_show at 0x7fd3d69e21b8>
:
def catch_assertionerror(function):
@wraps(function)
def handle_problems(*args, **kwargs):
...
return handle_problems
は、元の関数の情報を保持しますが
問題があることをあなたにも示しています。
# When trying to define the class
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 6, in X
File "<stdin>", line 2, in catch_assertionerror
File "/usr/lib/python2.7/functools.py", line 33, in update_wrapper
setattr(wrapper, attr, getattr(wrapped, attr))
AttributeError: 'property' object has no attribute '__module__'
関数を呼び出す場所にコードが表示されていません – hspandher
私はインタラクティブなPythonセッションで "もっと簡単な例"を試したところ、期待どおりに動作しています。どのようにこのコードを実行していますか? – SpoonMeiser