@f
def g():
...
f是一个Decorator,这意味着f是一个函数会把引用带入其他函数,并且返回另一个函数的引用
先来看这个函数,每次调用mult_fn都会返回一个新的函数,double triple都是新的函数
def mult_fn(N):
def multiply(x):
return x * N
return multiply
double = mult_fn(2)
triple = mult_fn(3)
print(double(10))
#20
decorator就和这个有点像
def function_A():
print("A")
def decorate(fn):
print("decorating!")
return function_A
def function_B():
print("B")
function_B = decorate(function_B)
function_B()
#decorating!
#A
等同于
def function_A():
print("A")
def decorate(fn):
print("decorating!")
return function_A
@decorate
def function_B():
print("B")
function_B()
#decorating!
#A
counts = {}
def count_me(fn):
counts[fn.__name__] = 0
def wrapper():
counts[fn.__name__] += 1
fn()
return wrapper
@count_me
def f():
print("f")
@count_me
def g():
print("g")
g();f()
counts
#{'f': 1, 'g': 1}
用decorate把元素增加到list中
def abs(x):
return x if x > 0 else -x
tests = []
def test(fn):
tests.append(fn)
return fn
@test
def test_neg():
assert abs(-1) == 1
assert abs(-3) == 3
@test
def test_pos():
assert abs(1) == 1
assert abs(3) == 3
@test
def test_zero():
assert abs(0) == 0
passing = 0
failing = 0
for test_fn in tests:
try:
test_fn()
passing += 1
except Exception:
failing += 1
print("PASS", passing, "FAIL", failing)
#PASS 3 FAIL 0
routes = {}
def route(url):
def wrap(fn):
routes[url] = fn
return fn
return wrap
@route("/")
def home():
print("home")
@route("/donate.html")
def donate():
print("donate")
for resource in ["/", "/donate.html", "/missing.html"]:
fn = routes.get(resource)
if fn == None:
print("404!")
continue
fn()
#home
#donate
#404!