22

__repr__クラス定義でメソッドを設定する例を見ただけです。__repr__定義内または定義後にfor関数を変更することは可能ですか?

私は成功せずに試みました...

>>> def f():
    pass
>>> f
<function f at 0x1026730c8>
>>> f.__repr__ = lambda: '<New repr>'
>>> f
<function __main__.f>
4

4 に答える 4

26

はい、あなたが実際に関数である関数を放棄することをいとわないのであれば。

まず、新しいタイプのクラスを定義します。

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>'

于 2012-06-04T01:52:58.307 に答える
9

いいえ、代わりにrepr(f)行われるためです。type(f).__repr__(f)

于 2012-06-04T01:44:06.510 に答える
5

__repr__そのためには、指定されたクラス(この場合は組み込み関数クラス( ))の関数を変更する必要がありますtypes.FunctionType。Pythonでは組み込みクラスを編集できず、サブクラス化するだけなので、編集できません。

ただし、従うことができる2つのアプローチがあります。

  1. kwatfordが提案したようにいくつかの関数をラップします
  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__は必ずしも望ましいとは限りませんが、このアプローチは最終的にはあなたが望むことを正確に実行することになります。

于 2012-06-04T07:56:32.893 に答える
1

これは難しいようです。Kwatfordのアプローチは、クラス内の関数では機能しないため、この問題を部分的にしか解決しません。Pythonクラスメソッドの装飾selfで説明されているように、位置引数のように扱われるため、インスタンスをデコレータに渡すにはどうすればよいですか?-ただし、残念ながら、この質問の解決策は、カスタムを使用してオーバーライドする__get__()ため、この場合には適用できません。functools.partial__repr__()

于 2021-04-04T11:55:57.767 に答える