Scopes 作用域
Closures 閉包
Decorators 裝飾器
Python Scopes 作用域
網路上大部分是用 LEGB 的方式來描述 Scopes 作用域
Local → Enclosed → Global → Built-in
Decorators 裝飾器
Decorator 程式範例
1. Function-based Decorators
注意:註解中的數字是執行順序,下同。
# Decorator Function Sample
def logged(func):
print('scope of logged') # 2 進入logged scope
print("Entering function name is: {}".format(func.__name__)) # 3
def with_logging(*args, **kwargs):
print('scope of with_logging') # 6
print("Entering function name is: {}".format(func.__name__)) # 7
print("arg:",*args) # 8
print("kwarg:",**kwargs) # 9
result = func(*args, **kwargs)
print("Exited", func.__name__) # 11
return result
print('exit') # 4
return with_logging
print('start using decorator') # 1
@logged # 呼叫logged
def test(k):
print("execute k: {}".format(k)) # 10
return k
print('execute') # 5
print(test(10)) # 12
輸出
start using decorator scope of logged Entering function name is: test exit excute scope of with_logging Entering function name is: test arg: 10 kwarg: execute k: 10 Exited test 10
2. Class-based Decorators
# Decorator Class Sample
class decorator(object):
def __init__(self, f):
print('enter init')
self.f = f
print('exit init')
def __call__(self, *args, **kwargs):
print("Entering", self.f.__name__)
r = self.f(*args, **kwargs)
print("Exited", self.f.__name__)
return r
print('start decorator ')
@decorator
def hello(k):
print('inside hello')
return("k is: " + k)
print('excute')
print(hello('say hello!'))
輸出
start decorator enter init exit init excute Entering hello inside hello Exited hello k is: say hello!
3. 不帶參數的 Function-based Decorators
# 不帶參數的 Decorator Function
def decorator(f):
print("excute \"{}\" decorate".format(f.__name__))
def print_df(*args, **kargs):
print("print_df before call")
result = f(*args, **kargs) # 呼叫 hello(),並將回傳值傳遞給result
print("print_df after call")
print("印出回傳值: {}".format(result))
return result
return print_df
@decorator
def hello():
print("say hello.")
return "hello"
hello()
輸出
excute "hello" decorate print_df before call say hello. print_df after call 印出回傳值: hello
4. 帶參數的 Function-based Decorators
# 帶有參數的 Decorator Function
def parseDecorator(param1, param2):
print("excute 'parseDecorator'") # 解析parseDecorator內的參數
def decorator(f):
print("excute \"{}\" decorate".format(f.__name__))
def print_df(*args, **kargs):
print("params are: '{}', '{}' ".format(param1, param2))
print("print_df before call")
result = f(*args, **kargs) # 呼叫 hello(),並將回傳值傳遞給result
print("print_df after call")
print("印出回傳值: {}".format(result))
return result
return print_df
return decorator
@parseDecorator("param1", "param2")
def hello():
print("say hello.")
return "hello"
hello()
輸出
excute 'parseDecorator' excute "hello" decorate params are: 'param1', 'param2' print_df before call say hello. print_df after call 印出回傳值: hello
5. 不帶參數的 Class-based Decorators
# 沒有參數的 Decorator Class
class decorator():
def __init__(self, f): # 對參數、函式進行初始化
self.f = f
def __call__(self, *args, **kargs):
print("person1 before call")
result = self.f() # 呼叫 person1()獲得回傳值,並將回傳值assign給result
print("result: {}".format(result)) # 印出回傳值
print("person1 after call")
@decorator
def person1():
print("I'm person1")
return "person1"
person1()
輸出
person1 before call I'm person1 result: person1 person1 after call
6. 帶參數的 Class-based Decorators
# 有參數的 Decorator Class
class decorateFruitClass(object):
def __init__(self, fruit, amount):
self.fruit = fruit
self.amount = amount
def __call__(self, f):
def buy(*args, **kargs):
print("%s %s before call" % (self.amount, self.fruit))
result = f(*args, **kargs)
print("%s %s after call" % (self.amount, self.fruit))
return result
return buy
@decorateFruitClass('guava', 10)
def person1():
print("I'm person1.")
@decorateFruitClass('banana', 20)
def person2():
print("I'm person2.")
person1()
print('-------')
person2()
輸出
10 guava before call I'm person1. 10 guava after call ------- 20 banana before call I'm person2. 20 banana after call
本文程式碼示範皆來自:Tsung Yu Chen (CC BY 4.0) ,非常感謝!