同步发表于个人博客:2022-07-19 python练习-函数式编程(二)
# 1. 返回函数、闭包
import functools
import time
def cal_sums(*args):
def do_sum():
result = 0
for x in args:
result += x
return result
return do_sum
call_sum = cal_sums(1, 3, 5, 7, 9)
call_sum_two = cal_sums(1, 3, 5, 7, 9)
print(call_sum)
print(call_sum_two)
print(call_sum())
def count():
fs = []
for i in range(1, 4):
def f():
return i * i
fs.append(f)
return fs
f1, f2, f3 = count()
print(f1)
print(f1(), f2())
def count_two():
fs = []
def g(j):
def f():
return j * j
return f
for i in range(1, 4):
fs.append(g(i))
return fs
f4, f5, f6 = count_two()
print(f4(), f5(), f6())
# 练习 利用闭包返回一个计数器函数,每次调用它返回递增整数:
def createCounter():
x = 0
def counter():
nonlocal x
x += 1
return x
return counter
# 测试:
counterA = createCounter()
print(counterA(), counterA(), counterA(), counterA(), counterA()) # 1 2 3 4 5
counterB = createCounter()
if [counterB(), counterB(), counterB(), counterB()] == [1, 2, 3, 4]:
print('测试通过!')
else:
print('测试失败!')
# 2. 匿名函数
l = list(map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
print(l)
# 练习
# 请用匿名函数改造下面的代码:
def is_odd(n):
return n % 2 == 1
L = list(filter(is_odd, range(1, 20)))
M = list(filter(lambda x: x % 2 == 1, range(1, 20)))
print(M)
# 3. 装饰器
def print_date():
print('2022-07-10')
f = print_date
print(print_date.__name__)
print(f.__name__)
def log(func):
def wrapper(*args, **kw):
print('call %s():' % func.__name__)
return func(*args, **kw)
return wrapper
@log
def print_date():
print('2022-07-10')
print_date()
@log
def print_sth(str):
print(str)
return "print_sth_return"
p_r = print_sth("print-something")
print(p_r)
print(print_sth.__name__)
def log_fun_name(func):
@functools.wraps(func)
def wrapper(*args, **kw):
print('call %s():' % func.__name__)
return func(*args, **kw)
return wrapper
@log_fun_name
def print_sth(str):
print(str)
return "print_sth_return"
p_r = print_sth("print-something")
print(p_r)
print(print_sth.__name__)
# 练习 1.请设计一个decorator,它可作用于任何函数上,并打印该函数的执行时间:
def metric(fn):
@functools.wraps(fn)
def wrapper(*args, **kvs):
start_time = time.time()
result = fn(*args, **kvs)
end_time = time.time()
print('%s executed in %s ms' % (fn.__name__, end_time - start_time))
return result
return wrapper
# 测试
@metric
def fast(x, y):
time.sleep(0.0012)
return x + y;
@metric
def slow(x, y, z):
time.sleep(0.1234)
return x * y * z;
f = fast(11, 22)
s = slow(11, 22, 33)
if f != 33:
print('测试失败!')
elif s != 7986:
print('测试失败!')
# 练习2. 请编写一个decorator,能在函数调用的前后打印出'begin call'和'end call'的日志。
#
# 再思考一下能否写出一个@log的decorator,使它既支持:
# @log
# def f():
# pass
# 又支持
# @log('execute')
# def f():
# pass
def log(*text):
print(text)
def wrapper(func):
def excute(*args, **kvs):
print("Text:", text, "Length", len(text))
print("begin call")
result = func(*args, **kvs)
print("end call")
return result
return excute
return wrapper
@log("execute", "exg", "abcd")
def f():
return "Have Args"
print(f())
@log()
def f():
return "No args"
print(f())
#4. 偏函数
int2 = functools.partial(int, base=2)
print(int2("10000"))