函数

一、函数定义方法:

def fuc_name(value):    #fuc_name函数名,value为参数可以为多个,也可以没有参数
    "the function definition" #函数描述
    value+=1     #代码块
    return value    

#定义返回值:
若返回值=0,返回None
若返回值=1,返回object
若返回值>1,返回tuple
def test01():
    msg = 'test01'
    print(msg)


def test02():
    msg = 'test02'
    print(msg)
    return msg

def test03():
    msg = 'test03'
    print(msg)
    return 1,2,3,4,'a',['alex'],{'name':'alex'},None

def test04():
    msg = 'test03'
    print(msg)
    return {'name':'alex'}
t1=test01()
t2=test02()
t3=test03()
t4=test04()
print(t1)
print(t2)
print(t3)
print(t4)

 如果函数的返回值是一个函数名,则返回函数地址

def test1():
    print('in the test1')


def test():
    print('in the test')
    return test1


# print(test)
res = test()
print(res)
print(res())  # test1()
'''
result:
in the test
<function test1 at 0x008D92B0>
in the test1
'''

如果函数的返回值是一个func(),则运行完func后,再返回func的return

def bar():
    print('from bar')


def foo():
    print('from foo')
    return bar()


n = foo()
print(n)
'''
result:
from foo
from bar
None
'''

二、参数

1、形参只有在调用的时候才占内存

2、位置参数和关键字参数:

  位置参数必须一一对应,缺一不行,多一也不行

  关键字参数不必一一对应,缺一不行,多一也不行

  混合使用时,关键字参数在位置参数右边

3、默认参数

def handle(x,type='mysql'):
    print(x)
    print(type)
handle('hello')
handle('hello',type='sqlite')
handle('hello','sqlite')

4、参数组 :**字典 *列表

①*args

def test(x,*args):
    print(x)
    print(args)


test(1)    #args=()
test(1,2,3,4,5)    #args=(2,3,4,5)
test(1,{'name':'alex'})    #args=({'name': 'alex'},)
test(1,['x','y','z'])    #args=(['x', 'y', 'z'],),以一个整体传入
test(1,*['x','y','z'])    #args=('x', 'y', 'z'),按遍历方式传入
test(1,*('x','y','z'))    #args=('x', 'y', 'z')

②**kwargs

def test(x,**kwargs):
    print(x)
    print(kwargs)
test(1,y=2,z=3) #kwargs={'y': 2, 'z': 3}
test(1,1,2,2,2,2,2,y=2,z=3)#会报错
test(1,y=2,z=3,z=3)#会报错 :一个参数不能传两个值

③*args,**kwargs

def test(x, *args, **kwargs):
    print(x)
    print(args, args[-1])
    print(kwargs, kwargs.get('y'))


test(1,1,2,1,1,11,1,x=1,y=2,z=3) #报错,由于x赋值两次
test(1, 1, 2, 1, 1, 11, 1, y=2, z=3)
'''
args=(1, 2, 1, 1, 11, 1) args[-1]=1
kwargs={'y': 2, 'z': 3} kwargs.get('y')=2
'''
test(1, *[1, 2, 3], **{'y': 1})
'''
args=(1, 2, 3) args[-1]=3
kwargs={'y': 1} kwargs.get('y')=1
'''

三、局部变量与全局变量

全局变量变量名大写
局部变量变量名小写

局部作用域里的变量定义不影响作用域外,

如果函数中无global,调用时先在当前作用域中找,只能读取全局变量,不能重新赋值,

但对于可变类型,可对内部元素进行操作

name = "we"


def ex():
    name = 123
    print(name)


ex()  # 123
print(name)  # we
NAME = ["产品经理", "廖波湿"]


def qupengfei():
    global NAME
    NAME.append('XXOO')
    print('我要搞', NAME)


qupengfei()

函数内定义的变量外部不能调用:

name = "we"


def ex():
    name1 = 123
    print(name1)


ex()  # 123
print(name1)  # 报错

未调用函数之前,函数定义内的代码块不编译:

NAME = "杠娘"


def yangjian():
    # NAME = "史正文"
    global NAME
    NAME = "小东北"
    print('我要搞', NAME)


def qupengfei():
    # NAME = "基"
    print('我要搞', NAME)


qupengfei()
yangjian()
qupengfei()
'''
打印结果为:
我要搞 杠娘
我要搞 小东北
我要搞 小东北
'''

如果要在函数中更改全局变量要使用global,变量本质上就是全局那个变量,可读取和赋值,global放在局部变量前

name = "we"


def ex():
    global name
    name = 123
    print(name)


ex()  # 123
print(name)  # 123

四、函数的嵌套&调用与相对全局/局部变量

函数执行顺序

NAME = '海风'  # 第1步


def huangwei():  # 第2步:将函数体写入内存,但不执行
    name = "黄伟"  # 第4步
    print(name)  # 第5步

    def liuyang():  # 第6步:将函数体写入内存,但不执行
        name = "刘洋"  # 第8步
        print(name)  # 第9步

        def nulige():  # 第10步:将函数体写入内存,但不执行
            name = '沪指花'  # 第13步
            print(name)  # 第14步

        print(name)  # 第11步
        nulige()  # 第12步

    liuyang()  # 第7步
    print(name)  # 第15步


huangwei()  # 第3步
'''
运行结果:
黄伟
刘洋
刘洋
沪指花
黄伟
'''

无论嵌套几层,global永远代指最外层的绝对全局变量:

name = "刚娘"


def weihou():
    name = "陈卓"

    def weiweihou():
        global name
        name = "冷静"

    weiweihou()
    print(name)


print(name)
weihou()
print(name)
'''
执行结果:
刚娘
陈卓
冷静
'''

nonlocal,指定上一级变量,如果没有就继续往上直到找到为止:

name = "刚娘"


def weihou():
    name = "陈卓"

    def weiweihou():
        nonlocal name  # nonlocal,指定上一级变量,如果没有就继续往上直到找到为止
        name = "冷静"

    print(name)
    weiweihou()
    print(name)


print(name)
weihou()
print(name)
'''
result:
刚娘
陈卓
冷静
刚娘
'''

五、调用函数的向前引用:

函数==变量

1、调用函数前必须先定义函数

2、代码从上到下阅读,读到就将内容写入内存

正确示例:

def bar():
    print('from bar')


def foo():
    print('from foo')
    bar()


foo()
def foo():
    print('from foo')
    bar()


def bar():
    print('from bar')


foo()

错误示例:

def foo():
    print('from foo')
    bar()

foo()
def foo():
    print('from foo')
    bar()


foo()


def bar():
    print('from bar')

六、递归

1、必须有一个明确结束条件

2、每进入一次递归,问题规模应比上一次减小

3、递归效率不高,递归层数过多导致栈的溢出

递归问路(可断点理清思路)

person_list = ['alex', 'wupeiqi', 'linhaifeng', 'zsc']


def ask_way(person_list):
    print('-' * 60)
    if len(person_list) == 0:
        return '根本没人知道'
    person = person_list.pop(0)
    if person == 'linhaifeng':
        return '%s说:我知道,老男孩就在沙河汇德商厦,下地铁就是' % person
    print('hi 美男[%s],敢问路在何方' % person)
    print('%s回答道:我不知道,但念你慧眼识猪,你等着,我帮你问问%s...' % (person, person_list))
    res = ask_way(person_list)
    print('%s问的结果是: %s' % (person, res))
    return res


res = ask_way(person_list)
print(res)
NAME = '海风'  # 第1步


def huangwei():  # 第2步:将函数体写入内存,但不执行
name = "黄伟"  # 第4步
print(name)  # 第5步

def liuyang():  # 第6步:将函数体写入内存,但不执行
name = "刘洋"  # 第8步
print(name)  # 第9步

def nulige():  # 第10步:将函数体写入内存,但不执行
name = '沪指花'  # 第13步
print(name)  # 第14步

print(name)  # 第11步
nulige()  # 第12步

liuyang()  # 第7步
print(name)  # 第15步


huangwei()  # 第3步
'''
运行结果:
黄伟
刘洋
刘洋
沪指花
黄伟
'''



七、函数的作用域
函数的作用域只跟函数声明时定义的作用域有关,跟函数的调用位置无任何关系
注意:
  foo()()()的运行与结果
name = 'alex'


def foo():
    name = 'lhf'

    def bar():
        name = 'wupeiqi'
        print(name, 'in bar', sep=':')

        def tt():
            print(name, 'in tt', sep=':')

        return tt

    return bar


r1 = foo()
r2 = r1()  # tt
r3 = r2()
foo()()()
'''
result:
wupeiqi:in bar
wupeiqi:in tt
wupeiqi:in bar
wupeiqi:in tt
'''

八、匿名函数

形式:

  lamda 形参:返回值

直接打印匿名函数,返回值是函数地址

print(lambda x: x + 1)
'''
result:
<function <lambda> at 0x005D9268>
'''

单独调用匿名函数需要给匿名函数命名

func = lambda x: x + 1
print(func(10))
'''
result:
11
'''

返回多个值时要加括号(元组)

lambda x,y,z:(x+1,y+1,z+1)    #正常运行
lambda x,y,z:x+1,y+1,z+1    #报错

'''
正常函数定义时,return值系统直接转换成元组
'''
def test(x,y,z):
    return x+1,y+1  #----->(x+1,y+1)

九、函数式编程

更多内容见:egon09.blog.51cto.com/9161406/1842475

1、高阶函数:

  1、函数接收的参数是一个函数名

  2、返回值中包含函数名

# 函数接收的参数是一个函数名
def foo(n):  # n=bar
    print(n)


def bar(name):
    print('my name is %s' % name)


foo(bar('alex'))
# 返回值中包含函数
def bar():
    print('from bar')


def foo():
    print('from foo')
    return bar


n = foo()
n()

2、map函数

num_l = [1, 2, 10, 5, 3, 7]
# map示例
res = map(lambda x: x + 1, num_l)
print('内置函数map,处理结果', res)
'''
result:
内置函数map,处理结果 <map object at 0x0055C190>
'''
for i in res:
    print(i)
'''
result:
2
3
11
6
4
8
'''
print(list(res))
'''
由于前面
for i in res:
    print(i)
所以这里的result:
[]

如果没有
for i in res:
    print(i)
result:
[2, 3, 11, 6, 4, 8]
'''


# 对map函数的理解

def reduce_one(x):
    return x - 1


def map_test(func, array):  # func=lambda x:x+1    arrary=[1,2,10,5,3,7]
    ret = []
    for i in array:
        res = func(i)  # add_one(i)
        ret.append(res)
    return ret


print(map_test(lambda x: x + 1, num_l))
'''
result:
[2, 3, 11, 6, 4, 8]
'''

print('传的是有名函数', list(map(reduce_one, num_l)))
'''
result:
传的是有名函数 [0, 1, 9, 4, 2, 6]
'''
msg = 'linhaifeng'
print(list(map(lambda x: x.upper(), msg)))
'''
result:
['L', 'I', 'N', 'H', 'A', 'I', 'F', 'E', 'N', 'G']
'''

3、filter函数

# filter函数
movie_people = ['alex_sb', 'wupeiqi_sb', 'linhaifeng', 'yuanhao_sb']
print(filter(lambda n: not n.endswith('sb'), movie_people))
# --><filter object at 0x00502FD0>
res = filter(lambda n: not n.endswith('sb'), movie_people)
print(list(res))
# -->['linhaifeng']
print(list(filter(lambda n: not n.endswith('sb'), movie_people)))
# -->['linhaifeng']

对filter函数的理解

movie_people = ['alex_sb', 'wupeiqi_sb', 'linhaifeng', 'yuanhao_sb']


def filter_test(func, array):
    ret = []
    for p in array:
        if not func(p):
            ret.append(p)
    return ret


res = filter_test(lambda n: n.endswith('sb'), movie_people)
print(res)
# -->['linhaifeng']

4、reduce函数

python 3中调用reduce函数需要

from functools import reduce
from functools import reduce

num_l = [1, 2, 3, 100]
print(reduce(lambda x, y: x + y, num_l, 1))  # -->107

print(reduce(lambda x, y: x + y, num_l))  # -->106

对reduce函数的理解

num_l = [1, 2, 3, 100]


def reduce_test(func, array, init=None):
    if init is None:
        res = array.pop(0)
    else:
        res = init
    for num in array:
        res = func(res, num)
    return res


print(reduce_test(lambda x, y: x + y, num_l, 1))  # -->107

5、总结

map()处理序列中的每个元素,得到的结果是一个‘列表’,该‘列表’元素个数及位置与原来一样
filter遍历序列中的每个元素,判断每个元素得到布尔值,如果是True则留下来
reduce:处理一个序列,然后把序列进行合并操作
#filter()
people=[
    {'name':'alex','age':1000},
    {'name':'wupei','age':10000},
    {'name':'yuanhao','age':9000},
    {'name':'linhaifeng','age':18},
]
print(list(filter(lambda p:p['age']<=18,people)))
#reduce
from functools import reduce
print(reduce(lambda x,y:x+y,range(100),100))
print(reduce(lambda x,y:x+y,range(1,101)))

十、内置函数

详见https://docs.python.org/3/library/functions.html?highlight=built#ascii

原文地址:https://www.cnblogs.com/jiangzhch5/p/13257982.html