函数

定义函数

def < name >(arg1, arg2, ....argN):
    < statements >

定义一个函数的几个基本规则

  1. 函数代码块以 def 开头,后接函数标识符名称与圆括号;
  2. 所有传入的参数和自变量都必须放在括号内,可在括号内定义参数;
  3. 函数内容以冒号开始,并且需要缩进
  4. return [ 表达式 ] 结束函数,选择性的返回一个值给调用方,不带表达式的return相当于返回None
  5. 对于函数的定义来说:使用return语句可以向外提供该函数执行的一些结果


函数的参数

def mark(a,b=1,*c,**d):
    print(f'a = {a}, b = {b} ,c = {c} , d = {d}')

mark(1,5)
mark(1,5,9,"p")
mark(c=1,a=5)
mark(1,No = 18)

结果如下

a = 1, b = 5 ,c = () , d = {}
a = 1, b = 5 ,c = (9, 'p') , d = {}
a = 5, b = 1 ,c = (1) , d = {}
a = 1, b = 1 ,c = () , d = {'No': 18}

调用函数时,可以使用的5种类型的参数:

  1. 必须参数(位置参数) a
    必须参数在传入时必须以正确的顺序传入,调用时数量必须和声明时一样
  2. 关键字参数 mark(c=1,a=5)
    使用关键字参数允许调用函数时参数的顺序与声明时不一致,解释器能够用参数名匹配参数值
  3. 默认参数 b
    默认参数是在定义函数时,给参数一个默认值;调用函数时,如果没有传递参数,就会使用默认参数默
  4. 可变参数 *c,**d
    加了 * 或者 ** 的变量名会存放所有未命名的变量参数;如果在调用函数时没有指定参数,就是一个空元组(或空字典);
    *与 **的区别在于: * 一般储存未命名的非关键字参数(元组结构), **主要储存未命名的关键字参数(字典结构)
  5. 组合参数 在定义函数时同时使用上述多种类型的参数
    如示例,在定义参数时如果使用多种类型的参数,需遵从一定的顺序:
    必须参数,默认参数,可变参数,关键字参数


全局变量与局部变量

  • 局部变量
    在函数内定义的变量只能在函数内部被引用,这个变量的作用于是局部的(函数内)
  • 全局变量
    在函数外,一段代码最开始赋值的变量可以被多个函数引用,这就是全局变量
num = 100
def func():
    num = 200
    return num

print(num + 1)
print (func() + 1)

结果

101
201

在函数中使用某个变量时,如果该变量同时有局部变量和全局变量(变量名相同),默认引用局部变量;
如果需要在 函数中将某个变量定义为全局变量,需要在被定义的变量前加上关键字 global(global num)



(函数中)返回函数

  • 闭包:如果在一个函数内部中对外部函数(非全局作用下)的变量进行引用,内部函数就被认为是闭包(closure)
def sum_late(*arg): # 定义一个序列求和函数
    def clac_sum(): # 在函数内再定义一个函数
        ax = 0
        for n in arg: # 对函数sum_late的参数arg进引用
            ax = ax + n
        return ax # 返回变量ax,以得到求和值
    return clac_sum #函数sum_late执行的结果是返回函数clac_sum

print(sum_late(1,2,3,4)) # 将参数直接传入sum_late函数,得到一个字符串(就是函数sum_late)
orc = sum_late(1,2,3,4)  
print(orc()) # 写法等同于print(sum_late(1,2,3,4)())

结果如下

<function sum_late.<locals>.clac_sum at 0x00D13F18>
10


递归函数

如果一个函数在内部调用自身,这个函数就称作递归函数
def recurision():
return recurision()

按照计算n的求和来说
假如:add(n) = 1+2+3+4+…+n ,那么add(n) = add(n-1) + n

def add(n):  
    if n == 1:  
        return 1
    else:
        return add(n-1) + n

print(add(100))

对于函数add(),当传入参数时,执行的步骤如下(例:传入5)

add(5) =  add(4) + 5
       =( add(3) + 4) + 5
       =((add(2)) + 3 + 4) + 5
       =((add(1) + 2) + 3) + 4) + 5
       = 1 + 2 + 3 + 4 + 5
       = 15

尾递归优化

  • 在计算机中,函数的调用是通过栈(stack)这种数据结构实现的;
    每当进入一个函数调用,栈就会加一层浅栈;每当函数返回,减一层浅栈;
    栈的大小有限,一旦此种方式调用时传入的参数过大(递归调用的次数过多)会导致栈溢出。
    尾递归优化就是解决此类问题的方案之一
    具体定义:在函数返回时,调用函数本身,并且return语句不能包含表达式
def dda(n,m):
    if n == 1:
        return m
    else:
        return dda(n - 1,m + n)
print(dda(100,1))

对于函数dda(),当传入参数时,执行的步骤如下(例:传入5,1)

dda(5,1) = dda(4,6) = dda(3,10) = dda(2,13) = dda(1, 15) = 15

每一个步骤都是函数dda()调用然后返回的结果,始终只占用一层浅栈

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值