内置函数:

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是一个IteratorIterator(迭代器?)是惰性序列

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'))