Python第10讲

本文详细介绍了Python函数的各个方面,包括实参的类型,允许接收不定长参数的方式,如收集参数和关键字参数,以及如何处理它们。探讨了函数的返回值,包括直接使用和通过变量接收返回值。还详细讨论了函数的文档字符串,作用域的概念和分类,特别是如何在函数内部修改全局变量。最后,文章讲解了递归函数的工作原理,包括递归的基线条件和递归条件。
摘要由CSDN通过智能技术生成

函数

实参的类型

  • 实参可以传递任意类型的对象 —— 调用函数时,解释器不会检查实参的类型
    • 在函数中重新给形参赋值,不会影响其他变量
    • 如果形参执行的是一个对象,当通过形参取修改对象时,会影响所有指向该对象的变量(可以通过切片,copy()方法等传递参数,不会影响实参的变量)
> def fn(a):
> 	a[2] = 30
> 	print('a =',a,id(a))
> b = [1,2,3]
 
> # 直接传递实参
> fn(b)
> print('b =',b,id(b))
> a = [1, 2, 30] 1915510083976
> b = [1, 2, 30] 1915510083976

> # 通过切片传递实参
> fn(b[:])
> print('b =',b,id(b))
> a = [1, 2, 30] 3180397810568
> b = [1, 2, 3]  3180397810056

> # 通过copy()方法传递实参
> > fn(b.copy())
> print('b =',b,id(b))
> a = [1, 2, 30] 2444721476488
> b = [1, 2, 3]  2444721475976

不定长参数

  • 不定长参数分为收集参数和关键字参数
  • 定义收集参数方法 —— 定义函数时,在参数前面加上一个*,这个形参可以获取其他未定义参数的所有位置参数(每个函数有且只有一个收集参数)
    • 收集参数将获取到的所有实参放入到一个元组中(也称打包)
    • 收集参数可以在定义函数时写到任意位置,但不定长参数后面有参数时,必须使用关键字传递实参
    • 收集参数处理位置参数
> # 查看收集参数的类型
> def n(*args):
> 	print(args,type(args))
> n(1,2,3)
> (1, 2, 3) <class 'tuple'>

> # 收集参数没有实参时返回空元组
> def n(*args):
> 	print(args,type(args))
> n()
> () <class 'tuple'>


> # 位置参数在收集参数后面时必须指定关键字参数,否则报错
> def n(a,*b,c)
> 	print('a =',a)
> 	print('b =',b)
> 	print('c =',c)
> n(1,2,3,4,5)
> '''
> n(1,2,3,4,5)
> TypeError: n() missing 1 required keyword-only argument: 'c'
>'''

> n(1,2,3,4,c=5) #1是位置参数,2,3,4是收集参数,5是关键字参数
> a = 1
> b = (2, 3, 4)
> c = 5
  • 定义不定长关键字参数方法 —— 定义函数时,在参数前面加上两个**,这个形参可以获取所有其他未定义的关键字参数(每个函数有且只有一个关键字参数,并且必须在所有形参的最后)
    • 不定长关键字参数将获取到的所有实参放入到一个字典中
    • 处理不定长关键字参数
> # 定义不定长关键字参数必须在参数的最后,否则报错
> def a(**a,b):
> 	print ('a =',a)
> 	print ('b =',b)
> '''
> def a(**a,b):
> SyntaxError: invalid syntax
> '''

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

函数的返回值

  • 概念 —— 函数执行以后返回的结果
  • 返回值语句 —— return(指定函数返回值)
    • 可以直接使用函数的返回值,或通过一个变量来接收函数的返回值
    • return后面可以是任意对象
    • 如果函数没有返回值,或没有return语句,返回值为None
    • return语句后面的代码都不会执行,return执行后函数结束
> def fn():
>   return 123
> r = fn()
> print(r)
> 123  

> # 不使用return语句不能进行函数值的操作,因为返回值为None
> def fn():
> 	print(10)
> r = fn()
> print(r-3)
> '''
> File "<stdin>", line 1, in <module>
> TypeError: unsupported operand type(s) for -: 'NoneType' and 'int'
> '''

> # 使用return语句可以进行函数值的操作
> def fn():
> 	return 10
> r = fn()
> print(r-3)
> 7

文档字符串(长字符串)

  • 使用方法 —— 使用六个单引号(前3个,后3个,中间为字符串)
  • 查看函数、方法的文档 —— 使用help(),参数传递时不用带括号
> # 查看方法帮助文档
> help(list.copy)
> '''
> Help on method_descriptor:
> copy(self, /)
> Return a shallow copy of the list.
> '''

> # 查看函数帮助文档
> help(print)
> # 略

函数的作用域

作用域

  • 作用域定义 —— 变量生效的区域
作用域分类
  • 作用域分类 —— 全局作用域和函数作用域
    • 全局作用域
      • 在程序执行时创建,程序执行结束时销毁
      • 所有函数以外的区域都是全局作用域
      • 在全局作用域中定义的变量都是全局变量
      • 全局变量可以在程序的任意位置进行访问
    • 函数作用域
      • 函数作用域在函数调用时创建,在调用结束时销毁
      • 函数每调用一次,就会产生一个新的函数作用域
      • 在函数作用域中定义的变量都是局部变量
      • 局部变量只能在函数内部被访问
    • 注意事项:最内层函数可以访问从最内层开始到全局变量的全部函数。但反向(从全局变量访问到最内层函数)会报错(NameError)。
> a = 1
> def fn():
>   b = 2
>   print('函数内部:a =',a)
>   print('函数内部:b =',b)
> fn()
> print('函数外部 a =',a)
> 函数内部:a = 1
> 函数内部:b = 2
> 函数外部:a = 1

> # 函数外部调用函数内部变量会报错
> def fn():
>   a = 2
>   print('函数内部:a =',a)
> fn()
> print('函数外部 a =',a)
> # NameError: name 'a' is not defined
函数内部修改全局变量
  • 方法 —— 在函数内部使用(global 变量)语句,此时函数内所有声明后的变量修改都影响全局变量
> a = 1
> def fn():
>   global a
>   a = 10
>   print('函数内部:a =',a)
> fn()
> print('函数外部:a =',a)
> 函数内部:a = 10
> 函数外部:a = 10

递归函数

  • 一种解决问题的思想,和循环很像
  • 递归函数是在函数中自己调用自己

递归式函数需要的条件

  • 基线条件
    • 问题可以被分解为最小的问题,当满足基线条件时,递归就不在执行了
  • 递归条件
    • 将问题可以继续分解的条件
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值