Day9-python函数进阶

一、函数的返回值

1.什么是返回值

1). 返回值的作用: 将函数里面的数据传递到函数外面
2). 初学怎么确定需不需要返回值: 看函数的功能完成后会不会产生新的数据

3). 怎么确定函数返回值: 函数声明的时候return后面的值就是函数的返回值;如果没有return,函数的返回值就是None
a. return: 关键字;只能出现在函数体中
作用: 确定函数的返回值; 结束函数(执行函数体的时候如果遇到return函数直接结束,同时将return后面的值作为函数返回值)

4). 怎么获取函数返回值: 函数调用表达式的值就是函数的返回值(获取函数调用表达式的值)
函数调用表达式: 函数调用语句; 普通数据能做的事情函数调用表达式都可以

================1.确定函数返回===============

def yt_sum(num1, num2):
    return num1 + num2


def func1():
    print('=====')
    print('++++++')
    return     # return None
    print('------')


func1()

======================2.获取函数返回值====================

def func2(num):
    # num = 2
    # return 4
    return num*2

a.函数调用表达式可以给变量赋值

# a = 4; print(a)
a = func2(2)
print(a)

# b. print(4+2)
print(func2(2)+2)


# c. [4, 10]; a=4, [a,10]
list1 = [func2(2), 10]
print(list1)   # [4, 10]

# yt_sum(4, 5)
re = yt_sum(func2(2), 5)
print(re)    # 9


def func3():
    return []


# [].append(100)
list2 = func3()
list2.append(100)
print(list2)

2.函数调用过程

1). 执行过程:

a.回到函数声明的位置
b.传参 - 保证每个参数都值
c.执行函数体
d.执行完函数体确定返回值: 看执行完函数体的时候有没有遇到return,如果遇到了return后面的值就是返回值;没有遇到就是None
e.回到函数调用的位置(这个时候函数调用表达式的值才是函数的返回值)

2)内存变化: 函数的调用过程是一个压栈的过程

调用函数的时候系统会自动在栈区间为这个函数开辟一个专用的内存区域,专门用来保存在这个函数中声明的变量和产生的数据
(形参也是声明在函数的变量);当函数调用结束的时候,这个内存区域会自动销毁(销毁前会将返回值扔出来)


def func4(n):
    # n=3
    print(n)
    return n*2   # return 6


a = func4(3)   # a = 6
print(a)

print(func4(4)+2)

二、变量的作用域

1.变量的作用域 - 变量可以使用的范围

2.全局变量和局部变量

1). 全局变量

没有声明在函数中或者类中的变量都是全局变量;
全局变量从声明开始到文件结束任何地方都可以使用

2). 局部变量

声明在函数中的变量就是局部变量;
从声明开始到函数结束可以使用(形参是声明在函数中的变量)

==============全局变量===============

# a是全局变量
a = 10
# b是全局变量
for b in range(4):
    # c是全局变量
    c = 100
    pass


print('在外部:', a, c)
print('外部b:', b)

for x in range(3):
    print('循环中:', a, b, c)


def func1():
    print('在函数中:', a, b, c)


func1()

======================局部变量=====================


# aa和bb都是局部变量
def func2(aa):
    bb = 200
    print('函数内部:', aa, bb)

    def func3():
        cc = 300
        print('函数中函数:', aa, bb)
    func3()
    # print('函数内部:', cc)  # NameError: name 'cc' is not defined

func2(100)

# print('函数外部:', aa)   # NameError: name 'aa' is not defined
# print('函数外部:', bb)   # NameError: name 'bb' is not defined

3.global和nonlocal

global和nonlocal这两个关键字只能在函数体中使用

1). global

使用方法: 在函数中给变量赋值前加: global 变量名
作用: 在函数中声明全局变量

2). nonlocal

使用方法: 在函数中给变量赋值前加: nonlocal 变量名
作用: 在局部的局部中修改局部变量的值
"""

======================global的使用=====================

# 全局变量a1
a1 = 100
b1 = 100


def func4():

    global c1
    # 声明一个局部变量a1
    a1 = 200

    # 声明b1是全局变量
    global b1
    b1 = 200   # 修改全局变量的值

    c1 = 300

    # global d1 = 200   # 错误!

    # 使用的局部变量a1; 使用的是全局变量b1
    print('函数中:', a1, b1)


func4()
# 使用的是全局变量a1, b1
print('函数外部:', a1, b1, c1)

======================nonlocal的使用=====================


def func5():
    a2 = 100

    def func6():
        nonlocal a2
        a2 = 200

        # 这儿的a3必须上层函数中已经声明过才行
        # nonlocal a3
        # a3 = 400

        print('函数的函数中:', a2)
        return a2

    func6()
    print('函数中:', a2)
    # print('a3')    # SyntaxError: no binding for nonlocal 'a3' found


func5()

三、匿名函数

1.什么是匿名函数 --没有名字的函数

匿名函数还是函数,普通函数中除了声明函数的语法基本都适用于匿名函数

1). 声明匿名函数

函数名 = lambda 参数列表:返回值

相当于:
def ___ (参数列表):
return 返回值

2). 说明:

lambda --关键字,固定写法
参数列表 --形参:参数名1,参数名2,....
--固定写法
返回值 ---相当于普通函数中函数体中的return语句

用匿名函数实现求两个数的和

func = lambda num1, num2: num1 + num2

2. 匿名函数的调用和普通函数没有区别

print(func1(10, 20))
print(func1(num1=100, num2=200))

参数默认值

func2 = lambda a=1, b=2, c=3: print(a, b, c)

# def func2(a, b, c):
#     return print(a, b, c)

print(func2())
func2(b=20)

不定长参数

func3 = lambda *nums: sum(nums)
print(func3(10, 20, 30))
print(func3(1, 2, 3, 4))

注意:不支持类型说明

# func4 = lambda a: int, b: a*b

练习:写一个匿名函数判断指定的年是否是闰年

func1 = lambda n :  ( n%4 == 0 and n%100!=0 )or ( n%400 ==0)


print(func1(2000))

三、递归函数

1.什么是递归函数

声明函数的时候调用函数本身, 这样的函数就是递归函数(自己调用自己)
递归可以实现循环效果, 原则上除了死循环,其他的循环递归都可以实现

2.递归怎么用

使用递归的套路:

a.设置临界值 - 循环结束的条件(保证函数结束)
b.找关系 - 找f(n)和f(n-1)的关系
c.假设函数的功能已经实现,通过f(n-1)去实现f(n)的功能

练习1.写一个递归函数,计算1+2+3+...n

def yt_sum(n):
    # 1.找临界值
    if n == 1:
        return 1

    # 2.找关系
    """
    f(n) ->  1+2+3+...+n-1+n
    f(n-1) -> 1+2+3+...+n-1
    f(n) = f(n-1) + n
    """
    # 3.用f(n-1)实现f(n)的功能
    return yt_sum(n-1)+n


# print(yt_sum(100))
# print(yt_sum(10))
print(yt_sum(5))

"""
yt_sum(5): n=5; if 5==1;   return yt_sum(4)+5    1+2+3+4+5
yt_sum(4): n=4; if 4==1;   return yt_sum(3)+4    1+2+3+4
yt_sum(3): n=3; if 3==1;   return yt_sum(2)+3    1+2+3
yt_sum(2): n=2; if 2==1;   return yt_sum(1)+2    1+2
yt_sum(1): n=1; if 1==1; return 1
"""

练习2. 写一个递归函数,求斐波那契数列的第n个数

# 1,1,2,3,5,8,13,21,....
def series(n):
    # 1.找临界值
    if n == 1 or n == 2:
        return 1
    # 2.关系: f(n) = f(n-1)+f(n-2)
    return series(n-1)+series(n-2)


print(series(9))

# 练习:递归实现f(n)
"""
n = 4
*
**
***
****

n = 3
*
**
***
"""


def print_star(n):
    if n == 1:
       print('*')
       return

    # 关系: 实现f(n-1)的功能后,再打印一行n个*
    print_star(n-1)
    print(n*'*')


print_star(5)

你可能感兴趣的:(Day9-python函数进阶)