0

属性を持つメソッドがいくつかあります (.Net 用語を使用するため)。何かのようなもの。

#Example Usage
@RequireLoggedIn
def SomeAuthorisedFunction():
    # ...

属性は次のように定義されます。

def RequireLoggedIn(func):
    func.AuthenticationRequired = True
    return func

次に、これが を使用して設定されているかどうかを確認できhasattr(view_func, 'AuthenticationRequired')ます。私がやりたいことは、このようなものです...

@RequireRole('Administrator')
def SomeAuthorisedFunction():
    # ...

私はこのような属性を定義しようとしました:

def RequireRole(func, Role):
    func.RequiresRole = Role
    return func

しかし、@RequireRole('Administrator')結果は にmissing positional argument "Role"なり、@RequireRole(Role='Administrator')結果はになりますmissing positional argument "func"

属性のプロパティを指定するにはどうすればよいですか?

4

2 に答える 2

3

ネストされた関数を作成する必要があります。RequireRole関数は実際のデコレータ関数を返す必要があります:

def RequireRole(Role):
    def decorator(func):
        func.RequiresRole = Role
        return func
    return decorator

@expression構文は、次のセットアップの構文シュガーにすぎません。

@decorator
def foo(): pass

は次のように翻訳されます。

def foo(): pass
foo = decorator(foo)

代わりは。ただし、そのdecorator部分自体が式になることもあります。それがあなたがそれを使おうとしている方法です。したがって@RequireRole('Administrator')、デコレータとして使用する場合は、実際に次のようにします。

def SomeAuthorisedFunction():
    # ...
SomeAuthorisedFunction = RequireRole('Administrator')(SomeAuthorisedFunction)

そこでのdouble関数呼び出しに注意してください。これが、私のバージョンのRequireRole()がネストされた関数を返す理由です。適用するとこうなります。

  1. def SomeAuthorizedFunction(): functionbody実行されます。
  2. RequireRole('Administrator') is executed. It returns a scopedデコレータ()`関数。
  3. この返された関数が呼び出され、SomeAuthorizedFunctionステップ 1 の関数に渡されます。
  4. スコープ関数は、ステップ 2 で渡されたスコープ値を使用して、属性をdecorator()関数に追加します。関数が返されます。.RequiresRoleRoleRequireRole
  5. Python は、ステップ 4 の戻り値を name に割り当てますSomeAuthorizedFunction
于 2013-04-17T15:54:54.960 に答える