デコレータ
関数オブジェクトを:
Pythonのすべての目標
関数は(関数は、データ転送として使用することができる)ファーストクラスのオブジェクトである
1を参照することができる、すなわちFUNC = X
2の関数に渡されるパラメータとして使用することができる。
図3は、関数の戻り値として使用することができる
4よいですコンテナデータ型の要素として
実施例1
:DEF FUNC(X)
パス
リターンX
X = FUNC(10)関数は、関数以外の値を返すと呼ばれる
X = FUNC
Xを()
のLi = [1、X 2]
実施例2
DEF FUNC(バー):
bar()の
DEFバー():
パス
FUNC(バー)
。実施例3
DEF outter():
:DEFインナー()
印刷( 'インナー')
を返すインナー
X = outter()
X()
ピレン機能電話してセットを定義し
、相互にときに、2つの関数呼び出しを
再帰エラーの最大深さ超え
)(DEF FUNCを:
印刷( 'FUNC')
FUNC()
DEFバー():
プリント( 'バー')
FUNC()
FUNC()
実施例1のネストされた呼び出し
DEF MAX(X、Y):
IF X> Y:
リターンX
ほか:
リターンY
DEF MAX4(X、Y、Z、A):
RES = MAX(X、Y)
RES = MAX(RES、Z)
RES = MAX(RES、Q)
MAX4(1。 、2,3,4、)
実施例2つのネストされた定義
DEF関数func1():
DEF関数func2():
DEF FUNC():
プリント( 'AAF')
FUNC()
DEF関数func2()
関数func1()
3つの名前空間スコープ
3.1
内蔵された名前空間
グローバル名前空間
PS:内蔵のグローバル空間変数)は世界的な実効>>検索glsbals(あります
ローカル名前空間(関数[クラス]開いランタイムメモリ空間
互いに独立して各部分空間)
、その外側の空間にアクセスできるローカル名前空間
#2は、スコープの関係は既に関数定義相に固定され、
関数を呼び出します位置に関係なく、
以下の個人は理解できないことがあり
ますが、関数を定義するときに、関数名やメモリのアドレスとの対応は、現在のネームスペースに保存されますので、
関係の範囲は、既に機能の定義段階で固定されている。機能は、バンドから呼び出されたとき。ネームスペースが呼び出さ定義
。X = 1
:DEF F1()
DEF F2():
プリント(X)
リターンF2
X = 100
DEF F3(FUNC):
X = 2
FUNC()
X = 10000
F3(F1() )
#3は、スコープ参照:グローバル()、地元()約
関数内の名前空間があるローカル変数およびパラメータを含む、地元についての
)外側のネストされた名前空間の関数(一般的閉鎖を囲むは
、グローバル変数、関数定義グローバルモジュールの名前空間の
ビルトインモジュールの名前空間のビルトイン
ビルトイン()
グローバル()
囲み()
地元の人について()
フォークロージャー関数は
クロージャは何です:
組み込み関数他の関数を呼び出すときにクロージャは、組み込み関数は、名前空間の外側の関数内ではなく、現在のネームスペースからその変数の転送に優先順位を1与えるされています変数を抽出する:これはクロージャである
2意志機能のみ特定の機能(すなわち、ネストされた関数呼び出し)を可能にする、一緒にデータパッケージを必要とする:これはクロージャである
という名前の外部関数の内側層の部分的膨張を構築することによって、本質的に同様の機能スペースと機能の追加
関数オブジェクトの概念に基づいて、あなたは関数を呼び出すために、任意の位置に戻すことができますが、関係が決定された完全な関数の定義の範囲にあり、位置と機能を呼び出します何の関係もありません。
それは常に、データ処理として扱われる機能である優先スコープが付属しています。関数は、外部スコープ(グローバルしない範囲)の変数への参照を埋め込み含まれている場合、「ネストされた関数は」関数クロージャが閉鎖(クロージャ)呼ばれる
。X = 1
:DEF F1()
DEF F2を():
プリント(X)
を返すF2
DEFのF3():
。X = 3
F2 = F1()F1乃至#コール()関数が返すF2
F2()#かかわらず位置の呼び出し、場合関数定義役割関係に行う必要
F3 ()#結果1。
X = 1。
DEF外部():
X = 2
DEFインナー():
プリント(X)
インナーリターン
FUNC =表地()
FUNC()#2の結果は
デコレータ
?何であるか
のためのツール他の装飾機能
の原則
ソースコード変更することなく、装飾的な機能
2は、呼び出しは、関数に装飾されている方法は変更されません
:デコレータ
引数なしの装飾をコントロール:
書き込み:
最初のステップ
デフアウター(FUNC):(入ってくる装飾関数の名前)
DEFインナー(* argsを、** kwargsから):
リターンインナー
パートII
デフアウター(FUNC):(装飾された機能を着信名前)
DEFインナー(*引数、** kwargsから):
'コードブロック1'を印刷()
RES = FUNC(*引数、** kwargsから)
) 'ブロック2'(プリント
戻りRESは、
内部戻り
第3の部分
@outerを
FUNC DEF():
パス
デコレータ機能(案)
のインポート時
#DEFログイン(ファイル):
#inp_name =入力( '場所入力ユーザー名!')。ストリップ()
#inp_password =入力( '場所入力yuorパスワード')。ストリップ()
= 'UTF-をコードする#オープンで(ファイル、モード= 'R'、 :Fとして8' )
#日= []
Fの行のため#:
#iofo = line.strip()スプリット()
#date.append(iofo)
#場合inp_name == iofo [0] .strip()とinp_password == iofo [1]:
#リターン真
#リターン偽
#の
#の印刷(ログイン(ファイル= f'user_iofo '))
デフoutter(FUNC):
DEF、内側(* argsを、** kwargsから):
スタート= time.time ()
ログイン(* argsを、** kwargsから)
終了= time.time()
印刷(最終スタート)
インナーリターン
@outter
DEFログイン(ファイル):
。inp_name = INPUT( '!INPUT場所ユーザー名')ストリップ()
。inp_password = INPUT( 'yuorパスワードの入力場所')ストリップ()
オープン(ファイル、MODE =「R&LTと'=コード' UTF-8「)AS F:
DATE = []
Fの回線で:
。iofo = line.strip()スプリット()
()iofo date.append
IF inp_name == iofo [0] .strip( )とinp_password == iofo [1]:
リターン真の
リターンはFalse
「」「Trueに戻るべきではありません」「」#今の内側ログイン値を返しますので、
印刷(ログイン(ファイル= f'user_iofo「))
(印刷します真の)
改善が完了し、欠点がありました。
図1は、変化対応しない値戻らない
変化テキスト解釈対応する2を
デコレータは、(サブドラフト)改善
#インポート時間
#デフoutter(FUNC):
#
#defのインナー(* argsを、** kwargsから):
#内部.__ DOC __ =ログイン.__ doc__内の例題
#内部.__名前__ =ログイン.__ name__
#開始= time.time()
#RES =ログイン(*引数、** kwargsから)
#エンド= time.time()
#プリント(最終スタート)
#リターンRES
#は、内側返す
#
#
#@outter
#デフログイン(ファイル):
#inp_name =入力( '場所入力ユーザー名! ').strip()
#inp_password =入力('場所入力yuorパスワード')ストリップ()
R」、=コード'Fとして)UTF-8' #開く(ファイル、モード=':
#日付= []
Fの行のため#:
#iofo = line.strip()スプリット()
Date.append#(iofo)
#== [0] .strip()== iofoとinp_password iofo inp_nameのIF [1]:
#リターン真
#リターン偽
'#' 'は' 'Trueを返すべきではない'
(#を印刷ログイン(ファイル= f'user_iofo「))
#印刷(真)
#変更テキストドキュメントの名前トリッキー>私たちは、修正するためのツールを呼び出すよう
functoolsラップインポートから
インポート時間
DEF outter(FUNC):
@wraps(FUNC)
DEFインナー(*引数、** kwargsから):
スタートtime.time =()
RES = FUNC(* argsを、** kwargsから)
終了= time.time()
印刷(スタート・エンド)
の戻りRESは
インナーを返す
@outter
DEFログイン(ファイル):
inp_name =入力(「場所入力ユーザー名 !」)。ストリップ()
inp_password = INPUT( 'yuorパスワードのプレースINPUT')ストリップ()。
開くと(ファイル、MODE = 'R&LT'、=コード'UTF-8')AS F:
DATE = []
:Fにおける線に対する
iofo =行。 。ストリップ()スプリット()
(iofo)date.append
[1]:inp_name == iofo [0] .strip()== IF iofoとinp_password
リターン真の
リターンはFalse
'' 'Trueに戻るべきではありません' ''
印刷(ログイン(ファイル= f'user_iofo「))
印刷(真の)
印刷(ヘルプ(ログイン))
参照デコレータがあり
、外側と内側の関数の機能は、他のパラメータを渡すことができなかった一方で、内部の機能は、追加のパラメータを渡す必要が。
我々ので、すなわち、パラメータ渡すクロージャの層を追加する
最初のステップ
:DEF人参(X、Y)
DEF外部(FUNC)を:
パス
リターン表地()
ステップ
DEF人参(X、Y):
DEF外側(FUNC):
DEF内側():
パス
リターン内側
戻り外側()
第三步
DEF人参(X、Y):
DEF外側(FUNC):
DEF内(*引数、* * kwargsから):
プリント(x、y)の
集合= FUNC(*引数、** kwargsから)
リターンセット
戻りインナー
デフ人参(X、Y):
DEF外側(FUNC):
DEF(インナー*引数、** kwargsから)。
プリント(x、y)の
集合= FUNC(*引数、** kwargsから)
リターンセット
戻り内側
戻りアウター
個人的な理解デコレータ
引数なしデコレータを持つ:機能は、機能を拡張し、元の関数に機能を追加するために使用される
2の呼び出しと同じように動かない原則1ソースを
、そのまま元の関数のコードを維持しながら、新しい機能を追加する必要がある(1)== >>のみ(一例として、アウター機能付き)、再書き込み機能着信外側関数の本来の機能に、
及びその後外側の関数関数に拡張する新しい機能を追加(ネストされた関数を呼び出す)
(2)それは、コールが必要同じ方法は、(メソッドをコピーに使用することができます)良い解決策と呼ばれるが、新しい関数名と一貫性のあるマスの参加の本来の機能を呼び出すことが、元の関数に渡されることを確認している。
外側の関数のパラメータは、元の関数が含ま渡され、ありません元の関数と同じパラメータに関連付けることができる、我々は再び機能書き込むことができ
、内側の関数に渡されたパラメータの本来の機能を(内部機能を有する例えば)を、元の関数(定義されたネストされた関数)のパラメータを持つことが一致する
(3私たちは[入パラメータを呼び出すことができ、我々は、元の関数を渡すことを確認する必要があります]ので、我々は、渡された元の関数のパラメータを知っておく必要があるため)これだけでなく、外側または内側の関数内で再び関数を記述
が何であるかを、外側ので、最も外側にある機能 着信層(関数名)、第二内層機能、元の機能モードのパラメータを受信し、((*引数、** kwargsから)を使用して)元の関数に渡されるパラメータはされ
(4)関数に内部機能に加え関数内で、あなたが機能を追加したいので、我々は、代わりに元の関数の内部機能を使用することを、元の関数の内部パラメータを受信する責任がある。関数の内部
(5)最後に、()外はに割り当てられている)(アウター、その後、内部を返します元の関数の関数名。例ログイン=外側()=インナー。呼び出しログイン()コール)(内側に相当する機能は、これまでアウト完了する