python 3クローズドパッケージとアクセサリー
19660 ワード
クローズドパックとアクセサリー閉パッケージ デコレーション 標準ライブラリのデコレーション functools.lru_cache 単分派汎関数 クローズドパッケージ閉パケット値は、関数定義体における参照を含む役割ドメインを拡張する関数であるが、定義体に定義されていない非グローバル変数 である.
例1
上記の方法は効率的ではありません.すべての値を履歴に保存するには、現在の値と長さを格納するのがより良いです.
例2
例2 spyderプロンプトエラーではコンパイルできません.countが数値または可変のタイプである場合、count+=1文の役割はcount=count+1と同様にaverでcountに一度付与されると、countが局所変数になるので、countは自由変数ではなく、閉パケットに保存されません.例1で問題ないのはappendを呼び出しsumとlenに伝えるためである.解決方法:nonlocal を追加
デコレーション
简単な装饰器を実现する时、私达はこの関数が不十分だと感じて、私はこの関数の基础の上でいくつかの余分な共通の机能を広げたいと思って、しかしこの関数はまたとても重要なため、直接コードに侵入して変えることができなくて、加えてその他の関数もこのような机能が必要かもしれなくて、このような@xxxのものです
次のようになります.
factはclocked関数の参照を保存し、fact(n)を呼び出すたびにclocked(n)が実行され、clockedは大体次のことをしました.記録初期時間t 0 元のfact関数を呼び出し、結果 を保存する計算経過時間 収集データのフォーマット は、ステップ2の結果 を返す.
スタンダードライブラリの装飾器 functools.lru_cache singledispatch
functools.lru_cacheはメモ機能を実現し、時間のかかる関数結果を に保存する.
例3
改良:注意:lru_Cacheは、2つのオプションのパラメータを使用して構成できます.
maxsizeは、2のサブべき乗の呼び出し結果を格納する回数を指定します.typedパラメータがTrueに設定されている場合は、異なるパラメータを別々に保存します.ディクショナリは結果を格納するので、パラメータはハッシュ可能でなければなりません.
例1実現のclock装飾器の欠点:キーワードをサポートせず、唄装飾を隠した_name__および_doc__プロパティ、functoolsを使用します.wraps()は解決できます.
シングルディスパッチ汎関数
pythonはリロードメソッド関数をサポートしていないのでsingledispatch装飾器を使用して全体シナリオを複数のモジュールに分割します.
例1
def make_avg():
series = [] # ---
def ave(n): #|
series.append(n) #
total = sum(series) #|
return total/len(sries) ---
return ave
# :
a = make_avg()
a(10)
a(11)
上記の方法は効率的ではありません.すべての値を履歴に保存するには、現在の値と長さを格納するのがより良いです.
例2
def make_ave():
count=0
res = 0
def aver(n):
count += 1
res += n
return res / count
return aver
例2 spyderプロンプトエラーではコンパイルできません.countが数値または可変のタイプである場合、count+=1文の役割はcount=count+1と同様にaverでcountに一度付与されると、countが局所変数になるので、countは自由変数ではなく、閉パケットに保存されません.例1で問題ないのはappendを呼び出しsumとlenに伝えるためである.
def make_ave():
count=0
res = 0
def aver(n):
nonlocal count, res
count += 1
res += n
return res / count
return aver
デコレーション
简単な装饰器を実现する时、私达はこの関数が不十分だと感じて、私はこの関数の基础の上でいくつかの余分な共通の机能を広げたいと思って、しかしこの関数はまたとても重要なため、直接コードに侵入して変えることができなくて、加えてその他の関数もこのような机能が必要かもしれなくて、このような@xxxのものです
#
def deco(fun):
def wap(*args, **kargs):
time_start = time.time()
fun(*args, **kargs)
time_end = time.time()
print('running time :', time_end-time_start)
return wap
@deco
def Afun1(a, b,c):
time.sleep(1)
print('a+b+c=',a+b+c)
Afun1(1,3,4)
#7.7
'''
'''
import time
def clock(f):
def clocked(*args):
t0 = time.perf_counter()
result = f(*args)
ela = time.perf_counter() - t0
name = f.__name__
arg_str = ', '.join(repr(arg) for arg in args)
print('[%0.8fs] %s(%s) ->%r' % (ela, name, arg_str, result))
return result
return clocked
@clock
def snooze(sec):
time.sleep(sec)
@clock
def fact(n):
return 1 if n < 2 else n*fact(n-1)
if __name__=='__main__':
print('*'*40, 'calling snooze(.123)')
snooze(.123)
print('*'*40, 'calling snooze(6)')
fact(6)
次のようになります.
:
def snooze(sec):
time.sleep(sec)
clock(sbooze)
factはclocked関数の参照を保存し、fact(n)を呼び出すたびにclocked(n)が実行され、clockedは大体次のことをしました.
スタンダードライブラリの装飾器
functools.lru_cache
例3
@clock
def fibonacci(n):
if n < 2:
return n
return fibonacci(n-2) + fibonacci(n-1)
print(fibonacci(6))
# ,
改良:
import functools
@functools.lru_cache()
@clock
def fibonacci(n):
if n < 2:
return n
return fibonacci(n-2) + fibonacci(n-1)
print result:
[0.00000030s] fibonacci(0) ->0
[0.00000030s] fibonacci(1) ->1
[0.00002180s] fibonacci(2) ->1
[0.00000060s] fibonacci(3) ->2
[0.00004260s] fibonacci(4) ->3
[0.00000040s] fibonacci(5) ->5
[0.00006430s] fibonacci(6) ->8
8
lru_cache(maxsize=128, typed = False)
maxsizeは、2のサブべき乗の呼び出し結果を格納する回数を指定します.typedパラメータがTrueに設定されている場合は、異なるパラメータを別々に保存します.ディクショナリは結果を格納するので、パラメータはハッシュ可能でなければなりません.
例1実現のclock装飾器の欠点:キーワードをサポートせず、唄装飾を隠した_name__および_doc__プロパティ、functoolsを使用します.wraps()は解決できます.
def clock(func):
@functools.wraps(func)
def clock(*args, **kargs):
シングルディスパッチ汎関数
pythonはリロードメソッド関数をサポートしていないのでsingledispatch装飾器を使用して全体シナリオを複数のモジュールに分割します.
from functools import singledispatch
from collections import abc
import numbers
import html
@singledispatch # object
def htmlize(obj):
content = html.escape(repr(obj))
return '{}
'.format(content)
@htmlize.register(str)
def _(text): は ではありません
content = html.escape(text).replace('','')
return '{0}'.format(content)
@htmlize.register(numbers.Integral)
def _(n):
return ' {0}(0x{0:x})
'.format(n)