面接を恐れず、あなたを案内します。


前に書く
「デコラレータ」はPythonの高度な言語特性の重要な部分として、関数を修正するための超便利な方法であり、コードの可読性とメンテナンス性を効果的に向上させるために適切に使用することができ、非常に便利で柔軟です。
装飾器は本質的に関数です。この関数は他の関数をパラメータとして受け入れ、新しい関数に置き換えられるのが特徴です。
今このように見るとちょっとぼんやりしていますが、「装飾器」の原理を深く理解するためには、まず「関数の対象とは何か」「入れ子関数とは何か」「クローズドとは何か」を理解しなければなりません。この3つの問題については、かなり前の文章でもう書きました。下のリンクをクリックして見ればいいです。これも面接でよく聞く知識です。
https://www.jb51.net/article/158738.htm
飾り物
上の3つの問題を理解してください。実は簡単な点は変数に関数が割り当てられます。関数はネストできます。関数オブジェクトは別の関数のパラメータとして使用できます。
まず、一例を見てみます。この例では、前に述べたすべての知識を使いました。

def first(fun):
  def second():
    print('start')
    fun()
    print('end')
    print fun.__name__
  return second

def man():
  print('i am a man()')

f = first(man)
f()
上記コードの実行結果は以下の通りです。
start
i am a man()
end
マン
上のプログラムでは、これがfirst関数です。パラメータとしてマン関数を受信し、マン関数を新しい関数に置き換えます。これを見て気づきましたか?これは私が文章を始めた時に言った「装飾器」の説明と同じです。以上であれば、上記のコードをPythonの装飾器の定義と使い方に合うように改造します。具体的には次のようになります。

def first(func):
  def second():
    print('start')
    func()
    print('end')
    print (func.__name__)
  return second

@first
def man():
  print('i am a man()')

man()
上のコードは前のコードの役割と同じです。違いは前のコードが直接「目を開けて度胸を開く」のfirst関数を使ってマン関数をカプセル化しますが、上のこれは「シンタックス飴」を使ってマン関数をカプセル化します。文法飴とは何かを細かく突き詰めなくてもいいです。「@first」みたいな形のものだと知ったらいいです。
上記のコードの中で「@frist」はマン関数の上に、マン関数に対してファーストデコラを使用することを示しています。「@」装飾器の文法です。「first」は装飾器の名前です。
次に複雑な点の例を見てみます。この例を使って、「装飾器」の使用とPython言語の高級特性として興味をそそられている部分をよりよく理解します。

def check_admin(username):
  if username != 'admin':
    raise Exception('This user do not have permission')

class Stack:
  def __init__(self):
    self.item = []

  def push(self,username,item):
    check_admin(username=username)
    self.item.append(item)

  def pop(self,username):
    check_admin(username=username)
    if not self.item:
      raise Exception('NO elem in stack')
    return self.item.pop()
上記は特殊なスタックを実現しました。特に多くの場合、現在のユーザーがadminであるかどうかを確認するステップで判断します。現在のユーザーがadminでない場合、例外を投げます。上のコードには、現在のユーザの身元をチェックするための独立した関数check(u)が書かれています。adminは、pushとpopの中でこの関数を呼び出すだけでいいです。このような方式はコードの可読性を高め、コードの冗長性を減らします。プログラミングする時にこのような意識を持つことができることを望んでいます。
上記のコードを装飾器で書いた効果を見てみましょう。

def check_admin(func):
  def wrapper(*args, **kwargs):
    if kwargs.get('username') != 'admin':
      raise Exception('This user do not have permission')
    return func(*args, **kwargs)
  return wrapper

class Stack:
  def __init__(self):
    self.item = []

  @check_admin
  def push(self,username,item):
    self.item.append(item)

  @check_admin
  def pop(self,username):
    if not self.item:
      raise Exception('NO elem in stack')
    return self.item.pop()
「飾り器」と「飾り器」を使っていない2つの書き方を比べてみますと、一見、「飾り器」を使ってからコードの行数が多くなりましたが、コードが分かりやすく見えますか?飾りがない時、私達が先に見たのはcheck_です。adminという関数は、まずこの関数が何なのかを考えてから見ます。装飾器を使う時、私達が上がってきて見たのはスタックに対する操作語句です。adminは現在の関数の理解に全く干渉しないので、装飾器を使ったほうが可読性がより良いです。
前の文章で述べた「ジェネレータ」のように、Pythoonの高度な言語特性は使いやすいですが、乱用してはいけません。装飾器の文法は複雑で、上で略語した装飾器を通して見れば、完成したら調整が難しいです。そして「装飾器」を使うプログラムの速度は装飾器を使わないプログラムより遅いです。だから、具体的なシーンを具体的に見ます。
以上は面接を恐れないで、python装飾器の詳しい内容を理解することを連れて、もっと多いpython装飾器の資料に関して私達のその他の関連している文章に関心を持って下さい!