pythonアクセサリー機能と使用例の詳細

8455 ワード

この例ではpythonアクセサリーの機能と使い方について説明します.皆さんの参考にしてください.具体的には以下の通りです.
1、必須

####     ####
def foo():
  print 'foo'
 
foo   #     
foo()  #    foo  
 
####     ####
def foo():
  print 'foo'
 
foo = lambda x: x + 1
foo()  #      lambda   ,       foo  ,     foo       


2、需要が来た
ベンチャー企業にはNの業務部門、1つの基礎プラットフォーム部門があり、基礎プラットフォームはデータベース操作、redis呼び出し、API監視などの機能を提供する.ビジネス部門が基礎機能を使用する場合は、基礎プラットフォームが提供する機能を呼び出すだけでよい.次のようになります.

###############             ###############
def f1():
  print 'f1'
 
def f2():
  print 'f2'
 
def f3():
  print 'f3'
 
def f4():
  print 'f4'
 
###############     A             ###############
f1()
f2()
f3()
f4()
 
###############     B             ###############
f1()
f2()
f3()
f4()


現在、会社は秩序正しく行われていますが、以前は基礎プラットフォームの開発者がコードを書くときに検証に関する問題に注目していませんでした.つまり、基礎プラットフォームの提供機能は誰でも使用できます.基礎プラットフォームのすべての機能を再構築し、プラットフォームが提供するすべての機能に検証メカニズムを追加する必要があります.すなわち、機能を実行する前に、検証を行います.
ボスはLow Bに仕事を任せました.彼はそうしました.
各業務部門と交渉し、各業務部門が自分でコードを書き、基礎プラットフォームの機能を呼び出す前に検証します.えっ、これで基礎プラットフォームは何の修正も必要ありません.
当日Low Bは除名されました...
ボスはLow BBに仕事を任せました.彼はそうしました.
基礎プラットフォームのコードのみを再構築し、N業務部門が何も修正する必要がないようにする.

###############             ############### 

def f1():
  #   1
  #   2
  #   3
  print 'f1'

def f2():
  #   1
  #   2
  #   3
  print 'f2'

def f3():
  #   1
  #   2
  #   3
  print 'f3'

def f4():
  #   1
  #   2
  #   3
  print 'f4'
###############        ############### 
###     A            ### 

f1()
f2()
f3()
f4()

###     B             ### 

f1()
f2()
f3()
f4()


1週間後にLow BBは除名されました...
ボスはLow BBBに仕事を任せました.彼はそうしました.
基本プラットフォームのコードのみを再構築し、他のビジネス部門は変更する必要はありません.

###############             ############### 

def check_login():
  #   1
  #   2
  #   3
  pass

def f1():
  
  check_login()

  print 'f1'

def f2():
  
  check_login()

  print 'f2'

def f3():
  
  check_login()

  print 'f3'

def f4():
  
  check_login()
  
  print 'f4'


ボスはLow BBBの実現を見て、口元から少し喜びの笑いが漏れて、言葉が重くてLow BBBと話をしました.
ボスはこう言いました.
書き込みコードは開発閉鎖の原則に従い、この原則ではオブジェクト向けに開発されているが、関数式プログラミングにも適用され、簡単に言えば、実現された機能コードは修正されないことを規定しているが、拡張することができる.
クローズド:実装された機能コードブロックオープン:拡張開発
オープンクローズ原則を上記の要件に適用すると、関数f 1、f 2、f 3、f 4の内部でコードを修正することは許されず、ボスはLow BBBに実装案を与えた.

def w1(func):
  def inner():
    #   1
    #   2
    #   3
    return func()
  return inner
 
@w1
def f1():
  print 'f1'
@w1
def f2():
  print 'f2'
@w1
def f3():
  print 'f3'
@w1
def f4():
  print 'f4'


上記のコードについても、基礎プラットフォームのコードを修正するだけで、他のユーザが関数f 1 f 2 f 3 f 4を呼び出す前に「検証」操作を行うことができ、他の業務部門は何も操作する必要がない.
Low BBBは驚いて聞いたが、このコードの内部実行原理は何なのか.
ボスはちょうど怒って、突然Low BBBの携帯電話が地面に落ちて、ちょうど屏保はLow BBBの彼女の写真で、ボスは見るとすぐに震えて、笑って、Low BBBという友达を作りました.詳しく説明し始めました.
単独でf 1を例に挙げると、

def w1(func):
  def inner():
    #   1
    #   2
    #   3
    return func()
  return inner
@w1
def f1():
  print 'f1'


このコードを書き終わると(関数が実行されていない、実行されていない、実行されていない)、python解釈器はコードを上から下に説明します.手順は次のとおりです.

def w1(func): ==> w1       
@w1


そう、表面的に解釈器は、関数が呼び出されないまで内部コードが実行されないため、この2つのコードを説明するだけです.
表面的に解釈器は実際にこの2つの文を実行しますが、@w 1というコードには大きな文章があります.@関数名はpythonの文法糖です.
上記の例@w 1の内部では、次の操作が実行されます.
  • はw 1関数を実行し、@w 1の下の関数をw 1関数のパラメータとします.すなわち、@w 1はw 1(f 1)に等しいので、内部で実行されます.
    
      def inner:
        #  
        return f1()  # func   ,   func    f1
      return inner   #     inner,inner      ,     

  • は、実は元のf 1関数を別の関数の
  • に詰め込むことである.
  • 実行済みのw 1関数の戻り値を@w 1の下の関数に付与する関数名w 1関数の戻り値は、def inner:#return元f 1()#ここでf 1が元のf 1関数を表していることを検証し、この戻り値をf 1に再付与し、すなわち、新f 1=def inner:#return元f 1()を検証するため、以降、業務部門がf 1関数を実行しようとすると、新f 1関数が実行され、新f 1関数の内部で検証が実行され、元のf 1関数が実行され、元のf 1関数の戻り値が業務呼び出し者に返される.これにより、検証機能が実行する、元のf 1関数の内容が実行され、元のf 1関数の戻り値が業務呼び出し
  • に戻る.
    Low BBB分かったか?もし分からなかったら、私は夜あなたの家に行って解决してあげましょう!!!
    先に上記の流れを理解して、その後も更新を続けます...
    3、質疑応答時間
    質問:飾られた関数にパラメータがあれば?
    パラメータ:
    
    def w1(func):
      def inner(arg):
        #   1
        #   2
        #   3
        return func(arg)
      return inner
    
    @w1
    def f1(arg):
      print 'f1'
    
    

    2つのパラメータ:
    
    def w1(func):
      def inner(arg1,arg2):
        #   1
        #   2
        #   3
        return func(arg1,arg2)
      return inner
    
    @w1
    def f1(arg1,arg2):
      print 'f1'
    
    

    3つのパラメータ:
    
    def w1(func):
      def inner(arg1,arg2,arg3):
        #   1
        #   2
        #   3
        return func(arg1,arg2,arg3)
      return inner
    
    @w1
    def f1(arg1,arg2,arg3):
      print 'f1'
    
    

    質問:n個のパラメータを処理する関数を持つ装飾器を装飾できますか?
    
    def w1(func):
      def inner(*args,**kwargs):
        #   1
        #   2
        #   3
        return func(*args,**kwargs)
      return inner
     
    @w1
    def f1(arg1,arg2,arg3):
      print 'f1'
    
    

    質問:1つの関数は複数の装飾器で装飾できますか?
    
    def w1(func):
      def inner(*args,**kwargs):
        #   1
        #   2
        #   3
        return func(*args,**kwargs)
      return inner
     
    def w2(func):
      def inner(*args,**kwargs):
        #   1
        #   2
        #   3
        return func(*args,**kwargs)
      return inner
     
    @w1
    @w2
    def f1(arg1,arg2,arg3):
      print 'f1'
    
    

    質問:もっと吊り下げた装飾器はありますか.
    
    #!/usr/bin/env python
    #coding:utf-8
     
    def Before(request,kargs):
      print 'before'
       
    def After(request,kargs):
      print 'after'
     
     
    def Filter(before_func,after_func):
      def outer(main_func):
        def wrapper(request,kargs):
           
          before_result = before_func(request,kargs)
          if(before_result != None):
            return before_result;
           
          main_result = main_func(request,kargs)
          if(main_result != None):
            return main_result;
           
          after_result = after_func(request,kargs)
          if(after_result != None):
            return after_result;
           
        return wrapper
      return outer
       
    @Filter(Before, After)
    def Index(request,kargs):
      print 'index'
    
    

    4、functools.wraps
    上記の装飾器はすでにそのあるべきものを完成しているが
    機能、すなわち、装飾器内の関数は元の関数を指し、等しいのではなく、元の関数のメタ情報が装飾器関数の内部に付与されていないことに注意する.例:関数のコメント情報
    メタ情報なし:
    
    def outer(func):
      def inner(*args, **kwargs):
        print(inner.__doc__) # None
        return func()
      return inner
    
    @outer
    def function():
      """
      asdfasd
      :return:
      """
      print('func')
    

    @functoolsを使用する場合wraps装飾装飾器内の関数は,メタ情報と関数を指す.
    メタ情報:
    
    def outer(func):
      @functools.wraps(func)
      def inner(*args, **kwargs):
        print(inner.__doc__) # None
        return func()
      return inner
    
    @outer
    def function():
      """
      asdfasd
      :return:
      """
      print('func')
    
    

    Pythonに関する詳細については、「Pythonオブジェクト向けプログラム設計入門と進級チュートリアル」、「Pythonデータ構造とアルゴリズムチュートリアル」、「Python関数使用テクニックまとめ」、「Python文字列操作テクニックまとめ」、「Python符号化操作テクニックまとめ」、「Python入門と進級クラシックチュートリアル」などのトピックを参照してください.
    ここではPythonプログラムの設計に役立つことを願っています.