1 函数
1.1 实参的类型
实参可以传递任意类型的对象,如:int,boolean,str,function等。
由于在调用函数的时候,解析器不会检查实参的类型。
因此,在调用函数时,需要自己注意选择的实参的类型。
例:
代码:
def sum(a,b):
print(a,'+', b,'=' ,a + b);
sum(10,'20');
执行结果:
报错内容:TypeError: unsupported operand type(s) for +: ‘int’ and ‘str’
函数的代码块功能是计算选择的两个实参的和,但是我选择了int
和 str
类型的实参,又因为解析器是不会检查实参类型的,结果导致程序中断报错。
*1.2 关于实参与形参的扩展内容
如果形参是不可变对象,在函数中重新给形参赋值,不会影响对应的实参;如果形参是一个可变对象,当修改形参的对象时,会影响的对应的实参。
如何理解?
首先,是前半句:
代码 1:
c = 3
print('改前:c =', c, id(c))
def fn(a):
print('改前:a =', a, id(a))
a = 5 # 修改 a 的值
print('改后:a =', a, id(a))
fn(c)
print('改后:c =', c, id(c))
执行结果 1:
根据执行结果1可以得出: 在改前:a和c的id值相同,说明指向的是同一个对象;在改后:a 的id值发生变化,c 不变,说明:a = 5
这行代码的实际操作,是将 a 变量的值改了,让 a 指向了一个另一个对象。逻辑如下图:
然后,是后半句:
代码 2
c = [1, 2, 3]
print('改前: c =', c, id(c))
def fn(a):
print('改前: a =', a, id(a))
a[0] = 5 # 修改列表中索引为0的元素
print('改后: a =', a, id(a))
fn(c)
print('改后: c =', c, id(c))
执行结果 2:
根据执行结果2可以得出:在改前:a 和 c 指向的是同一个对象;在改后,a 和 c 仍然指向同一个对象,,而且它们中索引为 0 的元素发生了同样的改变。这说明:a[0] = 5
修改的是 a 指向的可变对象的value,a 变量的值并没有发生改变。逻辑如下:
2.不定长参数
概念:在定义函数的时候,可以在形参的前面加 *
,该形参可以获得之后所有位置参数,获取的实参返回到一个元组中。
这种操作称为:装包。
例1:
代码:
def fn(a, b, *c):
print('a =', a)
print('b =', b)
print('c =', c)
fn(1, 2, 3, 4, 5, 6, 7)
执行结果:
注:在形参中,带*
的形参只能有一个,否则会报错:
错误提示:SyntaxError: invalid syntax
不定长参数可以不用写在最后一位,但是不定长参数后面的参数,必须以关键字参数的形式传递实参。
*
形参只能接受位置参数,**
形参可以接受关键字参数。
它会将参数保存到字典中。**
形参在一个函数中只能有一个,并且必须在所有形参的后面。
3.函数的返回值
返回值是函数执行的结果,可以通过return()指定函数的返回值。return()执行后,函数会退出。
函数的返回值可以直接使用,也可以传递给变量。
例:
代码:
def fn():
return 123
a = fn()
print(a)
执行结果:
如果函数没有return
语句或写了return
但没有返回参数,则相当于return none
4.文档字符串
文档字符串是一种注释的方式,可以便于说明函数和参数的功能。
语法:
'''
注释
'''
help(函数)
例:
5.函数的作用域
作用域是指变量生效的区域。有局部变量和全局变量两种作用域的变量。
一般情况下,函数内部定义的变量无法在函数外被取到(局部变量)。而函数外部的变量(全局变量),不仅可以在函数外取到,也可以在函数内部取到。
全局作用域:在程序执行时创建,程序结束时销毁。所有函数以外的区域都是全局作用域。
函数作用域:在函数调用时创建,调用结束时销毁。函数每调用一次就会产生新的函数作用域。函数中定义的变量都是局部变量,只有在函数内部才能访问。
例:
代码:
def fn():
a = 5
print('函数内 a =', a)
print('函数内 b =', b)
fn()
print('函数外 b =', b)
print('函数外 a =', a) # 这里会报错
执行结果:
根据执行结果可知:b 在函数内外都可以取到,a 在函数外取不到。
错误提示:NameError: name ‘a’ is not defined
5.1 global 关键字
根据以上的说法可以得知:通常情况下,在函数内部不能修改函数外部的变量(全局变量)但是,如果使用global
关键字,则可以实现在函数内部改变全局变量的值。
语法:
global 变量
例:
执行结果1:
执行结果2:
在使用了globa
l关键字声明变量后,a 变量就成了全局变量。
6.递归函数
递归函数与循环相似,是一种解决问题的思维方式,整体思想是将一个大问题拆分成多个小问题,知道无法再分解时,再解决问题。通常来说,递归函数会自己调用自己,且递归函数有两个条件:
- 递归条件 :问题可以继续分解的条件
- 基线条件 :问题无法再分解,停止递归的条件
例:创建一个函数,求任意数的阶乘
代码:
def fn(n):
if n == 1: # 基线条件
return 1
return n * fn(n - 1) # 递归条件
print(fn(10))
执行结果: