1

私のコードの一部では、Pythonデコレータライブラリのメモ化されたクラスを使用しています。

私が使用しているライブラリの1つは、関数のイントロスペクションを使用して、必要な引数の数を取得し、装飾された関数では失敗します。具体的には、co_argcount変数をチェックします。

if (PyInt_AsLong(co_argcount) < 1) {
      PyErr_SetString(PyExc_TypeError, "This function has no parameters to mini\
mize.");

argcountがメモ化された関数に転送されていないようです。

>>> def f(x):
...     return x
... 
>>> f.func_code.co_argcount
1
>>> g = memoized(f)
>>> g.func_code.co_argcount
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'memoized' object has no attribute 'func_code'

メモ化された関数が元の関数のように見え、味わい、匂いがするように、メモ化されたクラスを変更するにはどうすればよいですか?

4

2 に答える 2

3

署名を保持するデコレータを作成する必要があります。これを行う最も簡単な方法は、署名の保存を処理するライブラリhttp://pypi.python.org/pypi/decoratorを使用することです。

ライブラリの内部は非常に醜いです(それはexec!を使用します)が、それはそれらを非常にうまくカプセル化します。

于 2012-06-25T19:36:18.650 に答える
0

memoizedそれをクラスに追加します

def __getattr__(self, name):
    if name.startswith('func_'):
        return getattr(self.func, name)
    raise AttributeError

func_...したがって、属性ルックアップを元の関数に渡します。

これらの属性の書き込みを拒否する関数を作成することも__setattr__できますが、値を変更しようとしないことがわかっている場合は必要ありません。

于 2012-06-25T19:00:23.917 に答える