3

デコレータからローカル変数を取得しようとしています。例:

def needs_privilege(privilege, project=None):
    """Check whether the logged-in user is authorised based on the
    given privilege

    @type privilege: Privilege object, id, or str
    @param privilege: The requested privilege"""

    def validate(func, self, *args, **kwargs):
        """Validator of needs_privillige"""
        try: check(self.user, privilege, project)
        except AccessDenied:
            return abort(status_code=401)
        else: 
            return func(self, *args, **kwargs)

    return decorator(validate)

次のように関数を装飾した後:

 @needs_privilege("some_privilege")
 def some_function():
     pass

some_functionから'privilige'変数(validate()が使用)を取得したいと思います。1時間以上検索した後、私はかなり迷っています。これは可能ですか?

編集:私の問題をもう少し詳しく説明しましょう: some_functionを実行せずに文字列 "some_prvilege"を取得できますか?何かのようなもの:

a = getattr(module, 'somefunction')
print a.decorator_arguments

?これまで私を助けてくれてありがとう!

4

4 に答える 4

3

デコレータは基本的に、ユーザーが特定の関数を実行する権限を持っているかどうかを確認します。ラップされていた関数に特権を取得(アタッチ)する理由は実際にはわかりませんが、別の引数を追加せずにこれを行うことができます。すべての機能。

def needs_privilege(privilege, project=None):
    """Check whether the logged-in user is authorised based on the
    given privilege

    @type privilege: Privilege object, id, or str
    @param privilege: The requested privilege"""

    def validate(func, self, *args, **kwargs):
        """Validator of needs_privillige"""
        try: check(self.user, privilege, project)
        except AccessDenied:
            return abort(status_code=401)
        else:
            return func(self, *args, **kwargs)
    validate.privelege = privelege
    return decorator(validate)

ちなみに、デコレータは次のようになります。

def needs_privilege(privilege, project=None):
    def validate(func):
        def new_func(self, *args, **kwargs):
            try: 
                check(self.user, privilege, project)
            except AccessDenied:
                return abort(status_code=401)
            else:
                return func(self, *args, **kwargs)
        new_func.privilege = privilege
        return new_func
    return validate
于 2010-10-17T13:35:55.840 に答える
2

あなたはそれをパラメータとして渡すことができます:

def needs_privilege(privilege, project=None):
    """Check whether the logged-in user is authorised based on the
    given privilege

    @type privilege: Privilege object, id, or str
    @param privilege: The requested privilege"""

    def validate(func, self, *args, **kwargs):
        """Validator of needs_privillige"""
        try: check(self.user, privilege, project)
        except AccessDenied:
            return abort(status_code=401)
        else: 
            return func(self, privilege, *args, **kwargs)

    return decorator(validate)

@needs_privilege("some_privilege")
def some_function(privilege):
    pass
于 2010-10-17T12:35:42.423 に答える
1

decoratorモジュールが必要ない場合、問題ははるかに簡単になります。モジュールが厳密に必要でない場合はdecorator、次のようにデコレータを作成できます。

def needs_privilege(privilege, project=None):
    def validate(func):
        def _validate(self, *args, **kwargs):
            return func(self, *args, **kwargs)
        _validate.decorator_args=(privilege,project)
        return _validate
    return validate

@needs_privilege("some_privilege")
def some_function(self):
    pass

a = some_function
print(a.decorator_args)
# ('some_privilege', None)
于 2010-10-17T16:26:56.607 に答える
0

関数は、属性を持つこともできるオブジェクトです。デコレータで属性を設定できます。次に例を示します。

class TestClass(object):
    def needs_privilege(privilege, project=None):
        def wrapper(func):
            def validate(self, *args, **kwargs):
                """Validator of needs_privillige"""
                print 'validator check for %s' % privilege
                return func(*args, **kwargs)
            validate.privilege = privilege
            return validate

        return wrapper

    @needs_privilege("foo")
    def bar():
        print "called"

>>> test.TestClass().bar()
validator check for foo
called
>>> test.TestClass.bar.privilege
'foo'
>>> test.TestClass().bar.privilege
'foo'
于 2010-10-17T16:24:45.350 に答える