内置函数:
abs('A')
报错:TypeError: bad operand type for abs(): 'str'
传入的参数类型不对
自定义函数:
1 def my_abs(x): 2 if x >= 0: 3 return x 4 else: 5 return -x 6 7 my_abs('A')
报错:TypeError: unorderable types: str() >= int()
my_abs没有参数检查,会导致if语句出错,出错信息和abs不一样。所以,这个函数定义不够完善。
完善函数,对参数类型做检查:
def my_abs(x): #数据类型检查可以用内置函数isinstance()实现 if not isinstance(x,(int,float)): raise TypeError('bad operand type') if x >= 0: return x else: return -x my_abs('A')
TypeError: bad operand type
变量可以指向函数
#函数名其实就是指向函数的变量 f=abs print(f) #结果:<built-in function abs> f=abs print(f(-10)) #结果:10
高阶函数:一个函数接收另一个函数作为参数
def add(x,y,f): return f(x)+f(y) def oo(x): return x*x print(add(2,-3,oo))
13
map():
def f(x): return x*x r=map(f,[1,2,3,4]) #结果r
是一个Iterator
,Iterator(迭代器?)
是惰性序列 print(r) print(list(r))
<map object at 0x00000000021C7EF0>
[1, 4, 9, 16]
reduce:
#reduce把结果继续和序列的下一个元素做累积计算 from functools import reduce def add(x,y): return x*x+y print(reduce(add,[1,2,3]))
12
filter()
#filter()接收一个函数和一个序列,把传入的函数依次作用于每个元素,然后根据返回值true or false决定保留还是舍弃该元素 #删掉偶数 def is_odd(n): return n%2 == 1 print(list(filter(is_odd,[1,2,3,4,5])))
[1, 3, 5]
删除一个序列中的空字符串
def not_empty(s): return s and s.strip() list(filter(not_empty, ['A', '', 'B', None, 'C', ' '])) # 结果: ['A', 'B', 'C']
sorted
print(sorted([3,6,-1,0,-7],key=abs))
[0, -1, 3, 6, -7]
返回函数:
def lazy_sum(*args): def sum(): ax=0 for n in args: ax=ax+n return ax return sum f=lazy_sum(1,2,3) print(f) print(f())
<function lazy_sum.<locals>.sum at 0x000000000270B9D8>
6
闭包:
返回的函数并没有立刻执行,而是直到调用了f()
才执行
每次循环,都创建了一个新的函数,然后,把创建的3个函数都返回了
全部都是9
!原因就在于返回的函数引用了变量i
,但它并非立刻执行。等到3个函数都返回时,它们所引用的变量i
已经变成了3
,因此最终结果为9
。
返回闭包时牢记的一点就是:返回函数不要引用任何循环变量,或者后续会发生变化的变量。
def count(): fs=[] for i in range(1,4): def f(): return i*i fs.append(f) return fs f1,f2,f3=count() f4=count() print("f1:",f1,"f2:",f2,"f3:",f3) print(f4) print(f1()) print(f2()) print(f3())
f1: <function count.<locals>.f at 0x000000000273C9D8> f2: <function count.<locals>.f at 0x000000000273CB70> f3: <function count.<locals>.f at 0x000000000273CBF8>
[<function count.<locals>.f at 0x000000000273CC80>, <function count.<locals>.f at 0x000000000273CD08>, <function count.<locals>.f at 0x000000000273CD90>]
9
9
9
匿名函数(不需要定义函数名的函数)
a=map(lambda x:x*x,[1,2,3,4,5,6]) print(list(a))
lambda等价于
def f(x):
return x*x
lambda是匿名函数,冒号前面的x是函数参数,x*x是表达式(匿名函数规定只能有一个表达式),不用写return,直接把表达式的运算结果返回
匿名函数也是对象,可以赋值给变量:
f=lambda x:x+x print(f) print(f(4))
<function <lambda> at 0x00000000020CCBF8>
8
匿名函数也可以作为函数返回值:
def build(x,y): return lambda:x*x+y*y f=build(3,4) print(f())
25
偏函数
import functools #int函数的可选参数base,把二进制转换为十进制 a=int('00100000',base=2) #如果写函数的话 def int2(x,base=2): return int(x,base) print(int2('01010101')) #使用偏函数 #把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单 int3=functools.partial(int,base=2) print(int3('10101010'))