8

引数を受け入れ、その引数が None でないかどうかをチェックし、True の場合は装飾された関数を実行できるデコレータを使用したいと思います。

特定のインスタンス変数が None かどうかをチェックすることから始まる一連のクラス メソッドがあるため、クラス定義内でこのデコレータを使用したいと考えています。デコレータを使えばもっと綺麗になると思います。

私はこのようなことをしたいと思います:

# decorator
def variable_tester(arg):
    def wrap(f):
        def wrapped_f(*args):
            if arg is not None:
                f(*args)
            else:
                pass
        return wrapped_f
    return wrap

# class definition  
class my_class(object):
    def __init__(self):
        self.var = None

    @variable_tester(self.var) # This is wrong. How to pass self.var to decorator?
    def printout(self):
        print self.var

    def setvar(self, v):
        self.var = v

# testing code
my_instance = my_class()
my_instance.printout() # It should print nothing

my_instance.setvar('foobar')
my_instance.printout() # It should print foobar
4

1 に答える 1

7

いくつかのことをしたいので、これは少しトリッキーです。それぞれが少し厄介です: (1) 引数をデコレータに渡したい (2) その引数がインスタンスを参照するようにしたいが、インスタンス装飾の時点では存在しないため、何らかの形で延期する必要があります。関数や を使用することもできますitemgetterが、ここでは文字列を使用しますfunctools.wraps

何かのようなもの:

# really, it's variable-tester-factory
def variable_tester(target):
    def deco(function):
        def inner(self, *args, **kwargs):
            if getattr(self, target) is not None:
                return function(self, *args, **kwargs)
        return inner
    return deco

class my_class(object):
    def __init__(self):
        self.var = None

    @variable_tester('var')
    def printout(self):
        print self.var

動作するはずです:

>>> a = my_class()
>>> print a.var
None
>>> a.printout()
>>> a.var = 'apple'
>>> a.printout()
apple
于 2013-07-09T12:09:09.417 に答える