1

Python デコレータのアプリケーションが、それを適用した関数で何をしたかを確認する方法はありますか? たとえば、私が持っている場合

class A(object):

   @property
   def something(self):
       return 0

something実際に実行されたコードがどのように見えるかを知りたいです。これを行う方法はありますか?

4

1 に答える 1

5

デコレータはコードを生成しません。デコレータは、実際には構文糖衣に過ぎません:

@property
def something(self):
    return 42

実際には次のように解釈されます。

def something(self):
    return 42
something = property(something)

たとえば、記号に続く式@が評価され、結果が呼び出され、行に続く関数またはクラスに渡されます@。デコレータが返すものは何でも、元のオブジェクトを置き換えます。

イントロスペクションのために、@行は保持されません。ソース コード自体を解析して、存在するデコレータを検出する必要があります。デコレーターは、新しいオブジェクトを返す義務はありません。元のオブジェクトを変更せずに返すことができ、イントロスペクションでは違いを知ることができません。

最善の策は、デコレータのソースに戻ってコードを読むことです。propertyデコレーターは C で実装されていますが、記述子howtoには、同じことを行う Python 実装が含まれています。

class Property(object):
    "Emulate PyProperty_Type() in Objects/descrobject.c"

    def __init__(self, fget=None, fset=None, fdel=None, doc=None):
        self.fget = fget
        self.fset = fset
        self.fdel = fdel
        if doc is None and fget is not None:
            doc = fget.__doc__
        self.__doc__ = doc

    def __get__(self, obj, objtype=None):
        if obj is None:
            return self
        if self.fget is None:
            raise AttributeError("unreadable attribute")
        return self.fget(obj)

    def __set__(self, obj, value):
        if self.fset is None:
            raise AttributeError("can't set attribute")
        self.fset(obj, value)

    def __delete__(self, obj):
        if self.fdel is None:
            raise AttributeError("can't delete attribute")
        self.fdel(obj)

    def getter(self, fget):
        return type(self)(fget, self.fset, self.fdel, self.__doc__)

    def setter(self, fset):
        return type(self)(self.fget, fset, self.fdel, self.__doc__)

    def deleter(self, fdel):
        return type(self)(self.fget, self.fset, fdel, self.__doc__)
于 2014-01-08T17:49:35.837 に答える