python进阶-Python 进阶用法 (持续更新)
裝飾器(Decorator)
Python 的裝飾器是任何可調用對象(callable object),用于修改函數(Function)或類(Class)。按照用途可分為:
函數裝飾器
類裝飾器
裝飾器的接口定義可概括為:
接收某個函數或類的引用作為參數;
修改該函數或類并返回。
簡單函數裝飾器示例
理解裝飾器
def my_decorator(func):
def wrapped_func(arg):
print("Before calling " + func.__name__)
func(arg)
print("After calling " + func.__name__)
return wrapped_func
def foo(arg):
print("Hi, foo has been called with " + str(arg) )
print("We call foo BEFORE decoration:")
foo("no decoration"); print()
print("We NOW decorate foo with my_decorator... ")
foo = my_decorator(foo)
print("We call foo AFTER decoration:")
foo("decoration")
程序對應的輸出為:
We call foo BEFORE decoration:
Hi, foo has been called with no decoration
We NOW decorate foo with my_decorator...
We call foo AFTER decoration:
Before calling foo
Hi, foo has been called with decoration
After calling foo
上述例子中的用法在實際開發中并不常用,我們更傾向于下面的寫法。
語法糖寫法
Python 提供一種更簡潔、直觀的裝飾器寫法。例如我們可以把上述例子寫成更簡便的形式:
def my_decorator(func):
def wrapped_func(arg):
print("Before calling " + func.__name__)
func(arg)
print("After calling " + func.__name__)
return wrapped_func
@my_decorator
def foo(arg):
print("Hi, foo has been called with " + str(arg) )
foo("decoration")
函數裝飾器應用示例
統計函數調用次數
def call_counter(func):
def func_with_counts(arg):
func_with_counts.calls += 1
return func(arg)
func_with_counts.calls = 0
return wrapped_func
@call_counter
def foo(arg):
return "foo: " + str(arg)
print("foo has been called {} time(s)".format(foo.calls))
for i in range(0, 51, 10):
foo(i)
print("foo has been called {} time(s)".format(foo.calls))
程序對應的輸出結果是:
foo has been calld 0 time(s)
foo: 0
foo: 10
foo: 20
foo: 30
foo: 40
foo: 50
foo has been calld 6 time(s)
用記憶表(Memoization1)優化 Fibonacci 數列算法
def memoize(func):
memo = {}
def memoized_func(arg):
if arg not in memo:
memo[arg] = func(arg)
return memo
return memoized_func
@memoize
def fib(n):
if n == 0:
return 0
elif n = 1:
return 1
else:
return fib(n-1) + fib(n-2)
for i in range(20):
print(fib(i), end=", ")
print(fib(20))
程序對應的輸出結果是:
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765
類裝飾器
首先需要明確,Python 的裝飾器是任何可調用對象而不僅限于函數。我們可以定義一個類并使其對象可調用。例如我們可以定義一個帶緩存功能的類計算 Fibonacci:
class Fibonacci:
def __init__(self):
self.cache = {}
def __call__(self, n):
if n not in self.cache:
if n == 0:
self.cache[0] = 0
elif n == 1:
self.cache[1] = 1
else:
self.cache[n] = self.cache[n-1] + self.cache[n-2]
return cache[n]
fib = Fibonacci()
for i in range(20):
print(fib(i), end=", ")
print(fib(20))
程序對應的輸出結果是:
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765
因此,我們可以構建一個可調用對象并令其作為裝飾器。
在下面的例子中,我們用類裝飾器統計函數調用次數:
class CallCounter:
def __init__(self, func):
self.calls = 0
self.func = func
def __call__(self, arg):
self.calls += 1
return self.func(arg)
@CallCounter
def foo(arg):
return "foo: " + str(arg)
print("foo has been called {} time(s)".format(foo.calls))
for i in range(0, 51, 10):
foo(i)
print("foo has been called {} time(s)".format(foo.calls))
注意 Memoization 是專業術語,不是 Memorization。?
原文地址:https://www.cnblogs.com/LexLuc/p/10259110.html
總結
以上是生活随笔為你收集整理的python进阶-Python 进阶用法 (持续更新)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 个推的appid是指什么_推箱子软件介绍
- 下一篇: python音乐下载器交互界面_基于Py