3

私は次のようなクラスを持っています:

class Test(object):
    data = {}

    @add_to_data(1)
    def method_1(self, x, y):
        pass

    @add_to_data(1, 2, 3)
    def method_2(self, x, y):
        pass

    @add_to_data(5, 6, 7)
    def method_3(self, x, y):
        pass

「インポート時」にdataクラスの属性が次のようになるようにします。

>>> Test.data
{'method_1': [1], 'method_2': [1, 2, 3], 'method_3': [5, 6, 7]}

現在私はこれを持っています(dataですdefaultdict):

def add_to_data(*items):
    def decorator(func):
        for item in items:
            name = func.__name__
            cls = ??
            cls.data[name].append(item)
        return func
    return decorator

しかし、クラスオブジェクトを取得する方法がわかりません。何か助けはありますか?

4

2 に答える 2

4

sys._getframe()これは特にクリーンではありませんが、呼び出し元のスコープを検査するために使用してこれを行うことができます(デコレータdataは、ローカル変数であるクラス定義のコンテキストで呼び出されます。

したがって、次のようなものが機能するはずです。

import sys

def add_to_data(*items):
    def decorator(func):
        name = func.__name__
        data = sys._getframe(1).f_locals.get('data')
        if data is not None:
            data.setdefault(name, []).extend(items)
        return func
    return decorator

依存しsys._getframeたくない、またはより明示的なものが必要な場合は、@add_to_data関数デコレータでメソッドを適切な関数属性でマークし、クラスデコレータを使用しdataてマークされたすべてのメソッドからディクショナリを構築できます。

于 2012-12-14T02:33:26.763 に答える
1

クラスオブジェクトがまだ存在しないため、これを行うことはできません。

サブクラスのデコレータとして使用する基本クラスを作成するか、後でストレージをクラスの属性に@classmethodコピーするクラスデコレータまたはメタクラスと一緒に別の場所に物事を格納するデコレータを作成することで、同様のことを行うことができます。data

ええと、実際には、実際の目標が何であるか、そしてPy2とPy3のどちらを使用しているか(そしてCPythonとPythonのどちらだけを気にしているのか)を知らなければ、何を提案すればよいかわかりません。

于 2012-12-14T02:33:14.300 に答える