37

申し訳ありませんが、これは非常に広範な質問です。

以下のコードは、Web で見つけたものの一部です。私が興味を持っている重要なことは、@protected で始まる行です。これが何をどのように行うのか疑問に思っています。do_upload_ajax 関数を実行する前に、有効なユーザーがログインしていることを確認しているようです。これは、ユーザー認証を行うための非常に効果的な方法のようです。私はこの @ 関数の仕組みを理解していません - これが現実の世界でどのように実装されるかを説明するために誰かが私を正しい方向に導くことができますか? Python 3の回答をお願いします。ありがとう。

@bottle.route('/ajaxupload', method='POST')
@protected(check_valid_user) 
def do_upload_ajax():
    data = bottle.request.files.get('data')
    if data.file:
        size = 0
4

6 に答える 6

41

この巨大な答え/小説をよく見てください。これは私が出会った最高の説明の 1 つです。

私ができる最も短い説明は、デコレーターが関数を返す別の関数で関数をラップするということです。

たとえば、このコードは次のとおりです。

@decorate
def foo(a):
  print a

デコレータ構文を削除すると、次のコードと同等になります。

def bar(a):
  print a

foo = decorate(bar)

デコレーターは、動的に生成された関数に渡されて出力を変更するパラメーターを取ることがあります。

読んでおくべきもう 1 つの用語はClosureです。これは、デコレータが機能することを可能にする概念です。

于 2012-08-21T00:26:06.567 に答える
8

デコレータ構文:

@protected(check_valid_user) 
def do_upload_ajax():
    "..."

と同等です

def do_upload_ajax():
    "..."
do_upload_ajax = protected(check_valid_user)(do_upload_ajax)

ただし、同じ名前を3回繰り返す必要はありません。それ以上のものはありません。

たとえば、次の実装が可能ですprotected()

import functools

def protected(check):
    def decorator(func): # it is called with a function to be decorated
        @functools.wraps(func) # preserve original name, docstring, etc
        def wrapper(*args, **kwargs):
            check(bottle.request) # raise an exception if the check fails
            return func(*args, **kwargs) # call the original function
        return wrapper # this will be assigned to the decorated name
    return decorator
于 2012-08-21T00:56:42.507 に答える