__repr__
クラス定義でメソッドを設定する例を見ただけです。__repr__
定義内または定義後にfor関数を変更することは可能ですか?
私は成功せずに試みました...
>>> def f():
pass
>>> f
<function f at 0x1026730c8>
>>> f.__repr__ = lambda: '<New repr>'
>>> f
<function __main__.f>
はい、あなたが実際に関数である関数を放棄することをいとわないのであれば。
まず、新しいタイプのクラスを定義します。
import functools
class reprwrapper(object):
def __init__(self, repr, func):
self._repr = repr
self._func = func
functools.update_wrapper(self, func)
def __call__(self, *args, **kw):
return self._func(*args, **kw)
def __repr__(self):
return self._repr(self._func)
デコレータ関数を追加します。
def withrepr(reprfun):
def _wrap(func):
return reprwrapper(reprfun, func)
return _wrap
これで、関数とともにreprを定義できます。
@withrepr(lambda x: "<Func: %s>" % x.__name__)
def mul42(y):
return y*42
今repr(mul42)
生産'<Func: mul42>'
いいえ、代わりにrepr(f)
行われるためです。type(f).__repr__(f)
__repr__
そのためには、指定されたクラス(この場合は組み込み関数クラス( ))の関数を変更する必要がありますtypes.FunctionType
。Pythonでは組み込みクラスを編集できず、サブクラス化するだけなので、編集できません。
ただし、従うことができる2つのアプローチがあります。
独自のrepr関数を使用して独自の表現プロトコルを作成します。たとえば、最初にメソッドmyrepr
を検索する関数を定義できます__myrepr__
。これは関数クラスに追加することはできませんが、提案したとおりに個々の関数オブジェクト(およびカスタムクラスとオブジェクト)に追加できます。その後、デフォルトでreprになります。__myrepr__
見つかりません。これの可能な実装は次のとおりです。
def myrepr(x):
try:
x.__myrepr__
except AttributeError:
return repr(x)
else:
return x.__myrepr__()
__myrepr__
次に、メソッドを定義して関数を使用できますmyrepr
。__builtins__.repr = myrepr
または、関数をデフォルトrepr
にして、を使用し続けることもできますrepr
。編集__builtins__
は必ずしも望ましいとは限りませんが、このアプローチは最終的にはあなたが望むことを正確に実行することになります。
これは難しいようです。Kwatfordのアプローチは、クラス内の関数では機能しないため、この問題を部分的にしか解決しません。Pythonクラスメソッドの装飾self
で説明されているように、位置引数のように扱われるため、インスタンスをデコレータに渡すにはどうすればよいですか?-ただし、残念ながら、この質問の解決策は、カスタムを使用してオーバーライドする__get__()
ため、この場合には適用できません。functools.partial
__repr__()