程序员最近都爱上了这个网站  程序员们快来瞅瞅吧!  it98k网:it98k.com

本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长

+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

我的Python学习笔记_Day10 函数2

发布于2019-11-17 13:04     阅读(1153)     评论(0)     点赞(13)     收藏(1)


1. 函数的返回值

1) 返回值的作用

将函数里面的数据传递到函数外面

2) 初学者如何判断?

初学者怎么确定需不需要返回值:

看函数的功能完成后要不要产生新的数据

3) 怎么确定返回值?

函数声明时,函数体中,

return后面的值就是函数的返回值

若没有return,函数返回None

| 写法 | 说明 | 作用 |
| ------ | ---------------------------- | |
| return | 关键字
只能写到函数体里 |确定函数的返回值
结束函数|

执行函数体的时候如果遇到return,函数直接结束,同时将return后面的值作为返回值返回

def sum_int(num1: int, num2: int):
    return num1 + num2
  • 1
  • 2

4) 获取函数的返回值

获取函数调用表达式的值即可

例:用 3) 中的函数

result = sum_int(5, 2) + 2
print(result)  # 结果:9
  • 1
  • 2

注:函数调用表达式就是函数调用语句
普通数据能做的事函数调用表达式就能做

上例子中,sum_int(5, 2) 的返回值是7,所以在语句中,和7的作用一模一样,可以直接进行运算

2. 完整的函数调用过程

day9中的函数调用过程没有涉及到返回值,这里完善一下

1) 执行过程

a. 回到函数声明位置

b. 传参 - 保证每个参数都有值

c. 执行函数体

d. 执行完函数体确定返回值
看执行完函数体的时候有没有遇到return
如果遇到了return,后面的值就是返回值
没有遇到就返回None

e. 回到函数调用的位置
(这个时候函数调用表达式的值才是函数的返回值)

2) 内存变化

函数的调用过程是一个压栈的过程

调用函数的时候系统会自动在栈区间为这个函数申请一个专用的内存区域,专门用来保存在函数中声明的变量和产生的数据

注:形参也是声明在函数中的变量

当函数结束的时候,这个内存区域会自动释放

销毁前会将返回值扔出来

3. 全局变量和局部变量

1) 变量的作用域

即变量可以使用的范围

2) 全局变量

python: 没有声明在函数中或者类中的变量都是全局变量

全局变量从声明开始到文件结束任何地方都可以使用

for b in range(4):
    c = 100
    pass
print(b, c)  # 结果是3 100  这里b、c都是全局变量
  • 1
  • 2
  • 3
  • 4

3) 局部变量

声明在函数中的变量就是局部变量

(形参也是局部变量)

作用域:从声明开始到函数结束

def func2(aa):
    pass
func2(100)
print(aa)  # 报错,NameError,aa没有被定义
  • 1
  • 2
  • 3
  • 4

ps:python里,函数中还能声明函数

4) global和nonlocal

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

a. global
a = 100

def func4():
    a = 200
    print('函数中', a)

func4()
print('函数外', a)

# 结果:
# '函数中' 200
# '函数外' 100
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

出现上面这个现象的原因是:

a = 100 的这个a是全局变量

函数中,a = 200 的这个a是函数中的局部变量,是一个新的变量

函数结束时,值是200的局部变量a在内存里被释放

而原来的值是100的a还是原来的a

a = 100

def func4():
    global a  # 这个单独占一行!!!
    a = 200
    print('函数中', a)

func4()
print('函数外', a)

# 结果:
# '函数中' 200
# '函数外' 200
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
写法 说明
global 变量
变量 = …
函数中,在变量赋值前,
在函数中声明此变量为全局变量
b. nonlocal

使用场景:

在局部的局部中,修改局部的值

def func5():
    a = 100
    
    def func6():
        a = 200  # 这里也不行
        print(a)
    
    func6()
    print(a)
    
# 结果:200  100
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

在func6中,修改a的值也不行
因为a=200的a是func6的局部变量
同global一样,只是nonlocal在局部中使用

def func5():
    a = 100
    
    def func6():
        nonlocal a
        a = 200  # 这里可以
        print(a)
    
    func6()
    print(a)

# 结果:200  100
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

*但是nonlocal不能声明,只能修改!!!

def func5():
    a = 100
    
    def func6():
        nonlocal b  # 这里报错
        b = 200
        print(a)
    
    func6()
    print(a)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
写法 说明
nonlocal 变量
变量 = …
作用:
在子函数中,修改母函数的局部变量的值

nonlocal几乎不用,因为函数中声明函数已经很少见了,在这种情况下还有在子函数中修改母函数的局部变量,更罕见了

4. 匿名函数

1) 什么是匿名函数?

没有名字的函数

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

注:不支持普通函数中形参的参数类型说明

2) 声明匿名函数

lambda  参数列表:返回值
  • 1
写法 说明
lanmbda 关键字,固定写法
参数列表 形参:参数1,参数2,…
固定写法,不产生缩进
返回值 相当于普通函数的return语句

相当于:

def (参数列表):
	return 返回值
  • 1
  • 2

随堂练习:

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

func1 = lambda num1, num2: num1 + num2  # 声明
print(func1(10, 20))  # 结果:30
  • 1
  • 2

因为匿名,所以没法直接调用,这里暂时用一个变量去接

随堂练习:

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

loop_year = lambda year: (year % 4 == 0 and year % 100 != 0) or year % 400 == 0
  • 1

5. 递归函数

1) 什么是递归函数

在声明函数时调用函数本身的函数

即在声明的时候调用自己

def func1():
    func1()  # 报错
  • 1
  • 2

因为每次执行函数都会压栈,无限压栈内存怎么都不够

递归可以实现循环效果

原则上,除了死循环,其他的循环用递归都可以实现

递归比循环会消耗多的多的内存空间

2) 递归怎么用

使用递归的套路:

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

栗子:写一个递归函数,计算1+2+3+…+N

def sum_num(n: int):
    # 找临界值
    if n == 1:
        return 1

    # 找关系
    """
    f(n): 1+2+3+...+n
    f(n-1): 1+2+3+...+n-1
    f(n) = f(n-1) + n
    """

    # 用f(n-1)实现f(n)的功能
    return sum_num(n - 1) + n

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

n=5时的实现过程:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LLehdwrX-1573892642996)(D:\库\文档\截图\CSDN\递归.png)]

这里的 yt_sum() 和上面的 sum_num() 一样

随堂练习:

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

1,1,2,3,5,8,13,21…

def fibonacci(n: int):

    # 找临界值
    if n == 1 or n == 2:
        return 1

    # 找关系
    # f(n) = f(n - 1) + f(n - 2)
    
    # 用f(n-1)实现f(n)的功能
    return fibonacci(n - 1) + fibonacci(n - 2)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

练习:

写一个递归函数:

n = 4
*
**
***
****
  • 1
  • 2
  • 3
  • 4
  • 5

自己做的:

def star(n: int):
    if n == 1:
        return '*'
    return star(n - 1) + '\n' + '*' * n
  • 1
  • 2
  • 3
  • 4

老师答案:

def print_star(n):
    if n == 1:
        print('*')
        return
    print_star(n - 1)
    print(n * '*')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

作业

完善昨天的作业,尝试写出交互式学生管理系统

学生管理系统见day10的周末篇



所属网站分类: 技术文章 > 博客

作者:头疼不是病

链接:https://www.pythonheidong.com/blog/article/158090/3f617420d98e661549f2/

来源:python黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

13 0
收藏该文
已收藏

评论内容:(最多支持255个字符)