python基础(八):函数

        函数就是将一些语句集合在一起的部件,他们能够不止一次的程序中运行,函数还能够计算出一个返回值,并能够改变作为函数输入的参数。而这些参数在代码运行时每次都不同。以函数的形式去编写一个操作可以使它成为一个广泛的应用工具。

基本格式:

def  函数名:
    函数体
    return  返回值

定义和调用

定义函数按照前面的基本格式定义函数,调用函数时要使用函数名加括号来调用函数,括号中可以包含一个或多个参数。这些参数将会传递给函数头部的参数名。

#定义
def test(x,y):
    return x*y
#调用
test(5,10)

函数参数

必备参数

func(valule)   函数调用时会通过位置来匹配,调用函数时参数不能省略。

默认参数(关键字参数)

func(name=value)  函数如果在调用的时候不给参数,就按默认参数的值进行传递,如果在调用函数时给默认参数重新赋值则原值会被覆盖,

def func(name="Joe"):
    print(name)

func()
>>>Joe

func("AustinJoe") #func(name="AustinJoe")也是可以的
>>>AustinJoe

不定长参数

  1. func(*args) 将所有位置相关的参数收集到一个新的元组之中,并将这个元组值赋值给变量args。*可以匹配任意长度和数目的参数。
def func(*args):
    print(args)

func(*(1,2,3,4))#func(1,2,3,4)这种形式也是可以的
>>>(1, 2, 3, 4)

func([1,2,3],'hello','python')
>>>([1, 2, 3], 'hello', 'python')

   2.func(**kwargs)与上面类似,但是是将参数收集到字典中。

def func(**kwargs):
    print(kwargs)

func(a=1,b=2)
>>>{'b': 2, 'a': 1}

func(**{'a':1,'b':2})
>>>{'a': 1, 'b': 2}

 解包参数

在python中我们可以用*和**对参数解包。

def func(a,b,c,d):
    print(a,b,c,d)
args=(1,2,3,4)
func(*args)
>>>1 2 3 4
def func(a,b,c,d):
    print(a,b,c,d)
args={'o':1,'b':2,'c':3,'d':4}
func(**args)
>>>1 2 3 4

注意

参数类型是可以混合使用的,但必须遵循以下法则:

  1. 在函数调用中,参数必须以此顺序出现:位置参数,后面跟着任何关键字参数,然后是*args,最后跟着**kwargs。
  2. 在函数头部,参数必须以此顺序出现:一般参数后面紧跟着默认参数,如果有的话后面是*args,最后是**kwargs。

匿名函数:lambda

lambda是一个表达式,表达式创建了一个之后能够调用的函数,但是他返回了一个函数而不是将这个函数赋值给变量名。

其一般格式为:

lambda:argument1,argument2··· argumentN :expression using arguments
f = lambda x, y, z: x + y + z
print(f(2, 3, 4))
>>>9

lambda表达式常常与map()和filter()函数结合使用,我们接下来就学习这两个函数。

map():在序列中映射

map函数会对一个序列对象中的每个元素应用被传入的函数,并且返回了包含所用函数调用结果的一个列表。

l=list(map((lambda x:x+2),[1,2,3,4]))
print(l)

>>>[3, 4, 5, 6]
l=list(map(pow,[1,2,3],[5,6,7]))
print(l)
>>>[1, 64, 2187]

filter():过滤元素

filter()函数会根据测试函数过滤出一些元素。

l=list(filter((lambda x:x>0),range(-10,10)))
print(l)
>>>[1, 2, 3, 4, 5, 6, 7, 8, 9]

reduce()

reduce()函y数会对每一个元素应用函数并运行到最后结果。

from functools import reduce
result=reduce((lambda x,y:x+y),[1,2,3,4])
print(result)

>>>10

闭包:函数嵌套(间接函数调用)

闭包是指函数外面调用函数里面的的函数,即函数嵌套。

def main():
    print("hello world")
    def nest():
        print("我是嵌套的函数!")
    return nest
# 第一种形式
main()()

>>>hello world
>>>我是嵌套的函数!
# 第二种形式
m=main()
m()

>>>hello world
>>>我是嵌套的函数!

递归函数

递归函数的使用要注意:

  1. 递归的次数在python中是有限制的;
  2. 递归函数使用时占用的内存成几何量增长;
  3. 递归函数要有终止条件。
# 对一个列表求和
def sumtree(L):
    tot = 0
    for x in L:
        if not isinstance(x, list):
            tot += x
        else:
            tot += sumtree(x)
    return tot


L = [1, [1, 2, [6, 7], 3], 4, 5, [9, 8]]
print(sumtree(L))

>>>46

回调函数

函数A的执行取决于函数B中某一条件的执行,则函数A为回调函数。

def main(x):
    if x>5:
        print("回调函数未执行!!")
    else:
        return callback()

def callback():
    print("回调函数执行!!")

main(10)
>>>回调函数未执行!!
main(4)
>>>回调函数执行!!

作用域

作用域法则:

  1. 内嵌的模块是全局作用域;
  2. 全局作用域的范围仅限于单个文件;
  3. 每次对函数的调用都创建了一个本地作用域;
  4. 赋值的变量名除非声明为全局变量和非本地变量,否则均为本地变量;
  5. 所有其他的变量名都可以归纳为本地,全局或者内置的。
X=88
def func(Y):
    Z=X+Y
    return Z
print(func(12))
# 其中X和函数func都是全局变量名,而Y和Z均为本地变量名

global语句

global 语句用来声明一个全局或多个全局变量名。

X = 88

def func():
    global X
    X = 99

func()
print(X)
>> > 99

nonlocal语句

在声明nonlocal变量名时,该变量名必须存在函数的嵌套的作用域,即他们只能存在于一个嵌套的函数中,并且不能有一个嵌套的def中的第一次赋值创建。

def tester(start):
    state = start
    def nested(label):
        nonlocal state
        print(label, state)
        state += 1
    return nested
f = tester(0)
print(f('first'))
>>>first 0
print(f('second'))
>>>second 1
print(f('third'))
>>>third 2

 

posted @ 2018-08-04 21:26  AustinJoe  阅读(193)  评论(0编辑  收藏  举报