学习“廖雪峰的官方网站:Python教程”时做的笔记
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# 变量指向的对象可以是函数。
# 函数名其实就是指向函数的变量。
# builtins.abs = 10 在其他模块也会生效,导致无法计算绝对值。
# 高阶函数:函数接收另一个函数作为参数。
def add(x, y, f):
return f(x) + f(y)
# map
iterator = map(abs, range(-5, 5)) # 返回map object,是惰性的Iterator
print(list(iterator))
# reduce
from functools import reduce
reduce(pow, range(2, 5))
# 2,3,4 -> 2^3,4 = 8,4 -> 8^4 = 4096
DIGITS = {'0':0,'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9 }
# s = ''
# for i in range(48, 58):
# temp = '\'' + chr(i) + '\':' + str(i-48) + ','
# print(temp)
# s = s + temp
# print(s)
def char2num(s):
return DIGITS[s]
def str2int(s):
return reduce(lambda x, y: x * 10 + y, map(char2num, s))
# return reduce(lambda x, y: x * 10 + y, map(lambda x: DIGITS[x], s))
# lambda匿名函数:func(x, y) => x * 10 + y
print(str2int('1314'))
# filter
# 返回惰性序列。
# 函数返回值为True时取,否则舍。
print(list(filter(lambda x: x % 2 == 0, range(10))))
# sorted
# 默认升序,reverse反向,可接收key函数实现自定义排序。
print(sorted([3, -1, 8, -5], key = abs, reverse = True))
# 返回函数
def lazy_sum(*args):
def sum():
# 可以访问args,闭包结构。
ax = 0
pass
return ax
return sum
f = lazy_sum(range(5)) # 每次调用lazy_sum返回不同的函数对象。
f() # 被调用时才计算,万一不调用呢?就不用计算、节省资源。
# 使用闭包时牢记:返回函数不要引用任何循环变量,或者后续会发生变化的变量。
# 一定要引用循环变量时,内层再套一个函数并返回。
# 内层函数能访问外层函数的变量,但不能修改变量的指向(修改list内容不会改变指向),除非使用nonlocal关键字。
def createCounter():
n = 0 # n = [0] 也可
def counter():
nonlocal n
n += 1
return n
return counter
# 装饰器Decrator
# 不改变函数定义的前提下,增强函数功能,比如调用前后记录日志。
# 函数对象有一个__name__属性,可以拿到函数的名字。
import functools
# 3层装饰器
def log(text): # 自定义日志文本,故加一层
def decorator(func):
@functools.wraps(func) # 相当于wrapper.__name__=func.__name__。相当于wrapper = functools.wraps(func)(wrapper)?
def wrapper(*args, **kw): # 该参数组合可以接收任意参数
print('%s %s():' % (text, func.__name__))
return func(*args, **kw)
return wrapper
return decorator
@log('执行') # 相当于 now = log('执行')(now), 新now是wrapper。
def now():
print('2021-6-17')
now()
print(now.__name__) # 新now是wrapper。wrapper.__name__==func.__name__。
# 以下合并2层、3层装饰器
from inspect import isfunction
def logg(*text):
# 3层
def decoratorWithFunc(func):
@functools.wraps(func) # 相当于wrapper.__name__=func.__name__。相当于wrapper = functools.wraps(func)(wrapper)?
def wrapper(*args, **kw): # 该参数组合可以接收任意参数
print('begin call %s():' % (func.__name__))
for arg in text:
print(arg)
x = func(*args, **kw)
print('end call')
return x
return wrapper
# return decoratorWithFunc
# 2层
def wrapper(*args, **kw): # 该参数组合可以接收任意参数
func = text[0]
print('begin call %s():' % (func.__name__))
# for arg in text:
# print(arg)
x = func(*args, **kw)
print('end call')
return x
# return wrapper
# 兼容2层和3层
# print(isfunction(text[0]))
if len(text) > 0 and isfunction(text[0]):
return wrapper
return decoratorWithFunc
@logg('执行', 'execute') # logg('执行')(f)
# @logg # logg(f)
# @logg()
def f():
print('f being called')
pass
print('*****兼容2、3层')
f()
# 偏函数
# 参数个数太多时,可以固定部分参数,得到简化。
int2 = functools.partial(int, base=2) # 增加类似int(str, base=10)的函数。
print(int2('110')) # 2^2 + 2^1 + 2^0 = 6