1

次のコードを使用して、一種の型処理関数の登録を試みています。

types = {}
def type_handler(name):
    def wrapper(f):
        types[name] = f
        return f
    return wrapper

@type_handler('a')
def handle_a(a):
    ...

@type_handler('b'):
def handle_b(b):
    ...

def handle(x):
    types[x.name](x)

これは問題なく動作しますが、今はクラス内で動作させたいと思っています。
私はこれを試しました:

class MyClass(object):

    types = {}
    def type_handler(name):
        def wrapper(f):
            types[name] = f ## global name 'types' is undefined
            return f
        return wrapper

    @type_handler('a')
    def handle_a(self, a):
        ...

    @type_handler('b'):
    def handle_b(self, b):
        ...

    def handle(self, x):
        self.types[x.name](self, x)

しかし、それは言いglobal name 'types' is undefinedます。
に変えてみました

    def type_handler(name):
        def wrapper(f):
            MyClass.types[name] = f ## global name 'MyClass' is undefined
            return f
        return wrapper

しかし、今はこう言っていますglobal name 'MyClass' is undefined
これを機能させるにはどうすればよいですか?

私は次のようなことができることを知っています:

def handle(self, x):
    self.__getattribute__('handle_%s' % x.name)(self, x)

しかし、私は名前ベースのルックアップよりも関数登録を好みます。

4

1 に答える 1

3

私はスヴェン・マーナックに同意します。「少ない魔法」を使うべきです。ただし、ここに簡単な修正があります。

#decorator is declared outside of class and type dict is passed in as an argument
def type_handler(name, type_dict):
    def wrapper(f):
        type_dict[name] = f
        return f
    return wrapper

class MyClass(object):

    types = {}

    @type_handler('a', types)
    def foo_a(self, a):
        pass

    @type_handler('b', types)
    def foo_b(self, b):
        pass

バージョン 2

これはクラスをデコレータとして使用します:

class TypeHandler(object):
    def __init__(self, type_dict):
        self.types = type_dict

    def __call__(self, name):
        def wrapper(f):
            self.types[name] = f
            return f
        return wrapper


class MyClass(object):
    types = {}
    thandle = TypeHandler(types)

    @thandle('a')
    def foo_a(self, a):
        pass
于 2012-08-10T10:51:53.413 に答える