Pythonステップアップ-アクセサリー
15913 ワード
この章は、次の3つの部分に分かれています.関数役割ドメイン 閉パッケージ デコレーション 関数のスコープ
関数内部役割ドメインlocal>関数内部と埋め込み関数間enclosing>グローバル役割ドメインglobal>内蔵役割ドメインbuild-in
次に例を示します
説明:まず内部役割ドメインを検索し、SCOREの定義はありません.その後、関数も埋め込み関数を使用しません.その後、グローバル領域を検索してSCOREを見つけ、使用します.また、たとえばlen、max、minなどの関数python標準ライブラリでは、内蔵のbuild-inに属し、直接呼び出すことができますが、最後のステップまで呼び出されません.
インライン関数
1つの関数の内部定義では、この関数のみが使用できます.
クローズドパッケージ
Closure:内部関数でenclossing役割ドメインの変数を参照します.pythonでの関数の実質と属性について説明する必要があります.関数はオブジェクト です.関数の実行が完了すると、内部変数は に回収される.関数は、属性 を有する.関数は、戻り値 を有する.
関数はオブジェクトで、別の変数にコピーできます.
例を見てみましょう
印刷結果から、次の結論が得られます. func()はin_check() in_check()には変数scoreが使用され、func()で使用されているのと同じ変数が使用されています.内部変数が回収されていないのは、関数の参照カウントが0 ではないためです.
クローズドパッケージの役割
かばんを閉じると言ったが、彼は何の役に立つのだろうか.まず例を見てみましょう
ここでまた120点の制度があれば、コードを追加したり、Aレベルを総点数の80%に上げたりして、変えるのは面倒です.
したがって,閉包法を用いることは容易であり,これは2次元の変化を制御することに相当し,分数線の変化と比較が必要な分数の変化を同時に受け入れることができる.
これは,パッケージング性とコード多重性を体現している.
クローズドパッケージの使用例
もし私たちが今和を求める関数が必要なら.
パラメータのチェックがないため、実行には明らかにTypeErrorがあります.同様に、平均数を求める関数があれば、strタイプのパラメータを要求することはできません.そうすると、2つのタイプのチェックコードを書く必要があります.だから、簡略化すべきではないでしょうか.
分析実行プロセス:ステップ1:dec(my_sum)でmy_sum関数はパラメータとして入力され、print(‘dec’)を印刷し、in_を定義します.dec埋め込み関数を実行し、印刷print(「return in_dec」)を実行し、in_を返します.dec.そしてin_decはmyに値を割り当てますsum、特に今のmyに注意sumはもう元のmyじゃないsumです.これはステップ2の印刷からもわかりますが、タイプが変わりました.ステップ3:今my_sumは実はin_dec従って実行コードは、パラメータが直接returnステップ4:print(‘in_dec’)を正常に印刷し、文が一致していると判断してprint(‘return function(*args)’,function.)を印刷するname__),注意この時点でfunctionは元のmy_sum(また帰ってきた!)、最後にパラメータを入力し、結果を計算し、結果を返します.
ここで私たちは一周しました.つまりmy_に相当します.sumは、元のコードを変更する必要がなく、他の関数も使用できる追加の判断コードを追加しました.
デコレーションデコレーション関数 をデコレーションするために使用されるは、関数オブジェクト を返します.が装飾する関数識別子は、返される関数オブジェクト を指す.構文糖@dec コードの例:
main関数の最初の文を実行する前に、アクセサリーが実行されていることがわかります.つまりこの時my_sumは既に置き換えられています.次にコード実行は以前と同じです.
関数内部役割ドメインlocal>関数内部と埋め込み関数間enclosing>グローバル役割ドメインglobal>内蔵役割ドメインbuild-in
次に例を示します
SCORE = 60 #100
def check(score):
if score >= SCORE:
print('A')
else:
print('B')
SCORE = 60 #100
def check(score):
if score >= SCORE:
print('A')
else:
print('B')
if __name__=='__main__':
check(90)
#
A
説明:まず内部役割ドメインを検索し、SCOREの定義はありません.その後、関数も埋め込み関数を使用しません.その後、グローバル領域を検索してSCOREを見つけ、使用します.また、たとえばlen、max、minなどの関数python標準ライブラリでは、内蔵のbuild-inに属し、直接呼び出すことができますが、最後のステップまで呼び出されません.
インライン関数
1つの関数の内部定義では、この関数のみが使用できます.
SCORE = 60 #100
def check(score):
if score >= SCORE:
print('A')
else:
print('B')
def print_score(): #
print(score)
print_score() #
if __name__=='__main__':
check(90)
#
A
90
クローズドパッケージ
Closure:内部関数でenclossing役割ドメインの変数を参照します.pythonでの関数の実質と属性について説明する必要があります.
関数はオブジェクトで、別の変数にコピーできます.
Max = max #python
print(Max(3,2))
> 3
例を見てみましょう
SCORE = 60 #100
def check(score):
if score >= SCORE:
print('A')
else:
print('B')
def in_check():
print('score:',score)
#
print(in_check.__closure__)
in_check()
return in_check
if __name__=='__main__':
func = check(90)
print('---------------------------')
func()
print('---------------------------')
print(func.__closure__) #
#
A
(0x0000000002277498: int object at 0x000000005322AF80>,)
score: 90
---------------
score: 90
---------------
(0x0000000002277498: int object at 0x000000005322AF80>,) | |
印刷結果から、次の結論が得られます.
クローズドパッケージの役割
かばんを閉じると言ったが、彼は何の役に立つのだろうか.まず例を見てみましょう
SCORE_90 = 90 #150 90
SCORE_60 = 60 #100 60
def check_150(score):
if score > SCORE_90:
print('A')
else:
print('B')
def check_100(score):
if score > SCORE_60:
print('A')
else:
print('B')
if __name__=='__main__':
check_150(78)
check_100(78)
#
B
A
ここでまた120点の制度があれば、コードを追加したり、Aレベルを総点数の80%に上げたりして、変えるのは面倒です.
したがって,閉包法を用いることは容易であり,これは2次元の変化を制御することに相当し,分数線の変化と比較が必要な分数の変化を同時に受け入れることができる.
def set_aver_score(score):
def cmp(val):
if val > score:
print('A')
else:
print('B')
return cmp
if __name__=='__main__':
f_100 = set_aver_score(60)
print(f_100.__closure__, type(f_100))
f_100(86)
f_100(59)
#
# f_100 score,
(0x0000000002857498: int object at 0x0000000050CEABC0>,) 'function'>
A
B |
これは,パッケージング性とコード多重性を体現している.
クローズドパッケージの使用例
もし私たちが今和を求める関数が必要なら.
def my_sum(*args):
print('sum!')
return sum(args)
my_sum(1, 2, 3, 4, 5, 6)
my_sum(1, 2, 3, 4, 5, 'A')
#
TypeError: unsupported operand type(s) for +: 'int' and 'str'
パラメータのチェックがないため、実行には明らかにTypeErrorがあります.同様に、平均数を求める関数があれば、strタイプのパラメータを要求することはできません.そうすると、2つのタイプのチェックコードを書く必要があります.だから、簡略化すべきではないでしょうか.
def my_sum(*args):
print('sum!')
return sum(args)
def dec(function):
print('dec')
def in_dec(*args):
print('in_dec')
if len(args) == 0: #
return 0
for val in args:
if not isinstance(val, int): # , return
return 0
print('return function(*args)', function.__name__) # function
return function(*args)
print('return in_dec')
return in_dec
if __name__=='__main__':
my_sum = dec(my_sum) # 1
print(type(my_sum), my_sum.__name__) # 2
print('--------------')
my_sum(1, 2, 3, 4, '5') # 3
print('--------------')
my_sum(1, 2, 3, 4, 5) # 4
#
dec
return in_dec
'function'> in_dec
--------------
in_dec
--------------
in_dec
return function(*args) my_sum
sum!
分析実行プロセス:ステップ1:dec(my_sum)でmy_sum関数はパラメータとして入力され、print(‘dec’)を印刷し、in_を定義します.dec埋め込み関数を実行し、印刷print(「return in_dec」)を実行し、in_を返します.dec.そしてin_decはmyに値を割り当てますsum、特に今のmyに注意sumはもう元のmyじゃないsumです.これはステップ2の印刷からもわかりますが、タイプが変わりました.ステップ3:今my_sumは実はin_dec従って実行コードは、パラメータが直接returnステップ4:print(‘in_dec’)を正常に印刷し、文が一致していると判断してprint(‘return function(*args)’,function.)を印刷するname__),注意この時点でfunctionは元のmy_sum(また帰ってきた!)、最後にパラメータを入力し、結果を計算し、結果を返します.
ここで私たちは一周しました.つまりmy_に相当します.sumは、元のコードを変更する必要がなく、他の関数も使用できる追加の判断コードを追加しました.
デコレーション
def dec(function):
print('dec')
def in_dec(*args):
print('in_dec')
if len(args) == 0: #
return 0
for val in args:
if not isinstance(val, int): # , return
return 0
print('return function(*args)', function.__name__) # function
return function(*args)
print('return in_dec')
return in_dec
@dec
def my_sum(*args):
print('sum!')
return sum(args)
if __name__=='__main__':
print('__main__')
print(type(my_sum), my_sum.__name__)
res = print(my_sum(1, 2, 3, 4, '5'))
print(res)
print('--------------------------')
res = my_sum(1, 2, 3, 4, 5)
print(res)
#
dec
return in_dec
__main__
'function'> in_dec
in_dec
0
None
--------------------------
in_dec
return function(*args) my_sum
sum!
15
main関数の最初の文を実行する前に、アクセサリーが実行されていることがわかります.つまりこの時my_sumは既に置き換えられています.次にコード実行は以前と同じです.