函数(function)
函数简介:
- 函数也是一个对象(对象是内存中专门用来储存的一块区域)
- 函数可以用来保存一些可执行的代码,并且可以在需要时,对这些语句进行多次的调用
- 创建函数:
语法:
def 函数名([形参1,形参2,....]):
代码块
- 函数中保存的代码不会立即执行,需要调用函数代码才会执行
- 调用函数:
函数对象() # 可以重复使用
定义一个函数
def fn():
print("Heoll world")
fn()
函数的参数:
- 在定义函数时,可以在函数后面的()中定义数量不等的形参(也可以不设),多个形参之间使用,号隔开
- 形参(形式参数),定义形参就相当于在函数内部声明了变量,但并不会赋值
- 实参(实际的参数):
- 如果函数定义时,指定了形参,那么在调用函数时也必须传递实参,实参会将对应的值赋值给对应的形参
定义一个函数,用来求任意两个数的和
def sum(x, y):
print(x,"+",y,"=",x + y) # 使用形参来控制x于y的值
sum(100, 99) # 实参
- 练习1:
定义一个函数,可以用来求任意三个数的乘积
def mul(x =1,y =1,z =1): # x=1 设置默认值,当用户没有设置实参时,就输出默认值
print(x*y*z)
mul(3,4)
- 练习2:
定义一个函数,可以根据不同的用户名显示不同的欢迎信息
def welocme(username):
print("欢迎",username)
welocme("xx")
实参的传递方式
- 位置参数
- 位置参数就是将对应位置的实参复制给对应位置的形参
- 关键字参数
- 关键字参数,可以不按照形参定义的顺序去传递,而是根据参数名字去传递参数
def mul(x,y,z):
print(x*y*z)
mul(x=3,y=2,z=1)
函数调用时,解析器不会检查实参的类型,实参可以传递任意类型的对象(函数,字符串。浮点形,变量,序列.....)
def fn(a,b):
print(a+b)
fn(123,"456") # 报错
不定长参数
- 定义一个函数,可以求任意数字的和
在定义函数时,可以在形参的前面加一个*号,这样这个形参将会获得所有的实参,它将会把所有的实参保存到一个元组中
带星号的形参只能有一个,带星号的参数,可以和其他参数配合使用
def sum(*nums):
result = 0
for i in nums:
result += i
print(result, type(a)) # 获得结果,与nums的类型
sum(1, 2, 3, 4, 5)
可变参数不是必须写在最后,带*号的参数后的所有参数,必须已关键字的形式传递
def sum(a,*b,c):
print(a)
print(b)
print(c)
# sum(1,2,3,4,5,6,7,8,9) # 报错
sum(1,2,3,4,5,6,7,8,c=9)
*号形参只能接收位置参数,不能接收关键字参数
def sum(*a):
print(a)
sum(b=2,c=3) # 报错
**号形参可以接收其他的关键字参数,它会将这些参数统一保存到一个字典走,字典的key就是参数的名字,字典的value就是参数的值
**形参只能是有一个,并且必须写在最后一个
def sum(b,c,**a):
print(b,c,a,type(a))
sum(b=2,c=3,d=4,e=5)
参数的解包
t = (10,20,30,40)
传递实参时,也可以在序列类型的参数前添加*号,这样他会自动将序列中的元素依次作为参数传递
def fn(a,b,c,d,*e):
print(a,b,c,d)
fn(*t) # 使用*号对序列进行解包
d = {"a":100,"b":200,"c":300}
def fn(a,b,c):
print(a,b,c)
fn(**d) # 使用**号对字典进行解包
返回值
返回值就是函数执行以后返回的结果, 可以通过return来指定返回的结果
return后面跟的什么值,函数就会返回什么值
return后面可以跟任意对象(序列,函数,元组,字典,列表)
定义一个变量,来保存结果
def fn(*nums):
result = 0
for i in nums:
result += i
return (result)
print(fn(123,456,789))
return一旦执行return后的代码都不会执行,函数自动停止
def fn():
for i in range(5):
if i == 2:
#break # 用来退出循环
#continue # 用来跳过循环
return # 用来结束函数
print(i)
print("循环执行结束!") # 这个语句不会在return中输出
fn()
fn 和fn()的区别
def fn():
return 10
print(fn) # fn是函数对象,打印fn的对象id号,不会执行函数
print(fn()) # fn()是调用函数,打印fn的返回值,执行函数
文档字符串
help()是python中的内置函数,python中的函数的帮助文档
help(print)
自定义函数时添加帮助文档,直接在函数的第一行写一个字符串的文档字符串
def fn(a:int,b:bool,c:str) -> int: # 在定义函数时可以在参数后面添加类型,来方便help()查看 -> 后面是结果的类型
'''
这个一个文档的实例
函数的参数:
.... ....
'''
return 10
help(fn)
作用域和命名空间
作用域指的是变量生效的区域
全局作用域
- 全局作用域在程序执行时创建,在程序执行结束时销毁
- 所有函数以外的区域都是全局作用域
函数作用域
- 函数作用域在函数调用时创建,在调用结束时销毁
- 函数每调用一次就会产生一个新的函数作用域
d = 100 # 全局变量对函数内部和外部都有效
def fn():
a = 10 # a定义在函数内部,所以他的作用只能在函数内部使用,与外部没有关系
print("函数内部:",a)
print("函数内部:",b)
fn()
print("函数外部:",b)
# print("函数外部:",a) # 报错,函数外部无法调用到函数内部的变量
如果希望在函数内部修改全局变量,则需要使用global关键字,来声明函数
a = 10
def fn():
global a # 声明在函数内部的使用a是全局变量,此时去再去修改a时,结束全局变量了
a = 20 # 修改全局变量
print("函数内部:",a)
fn()
print("函数外部:",a)
命名空间
命名空间指的是变量储存的网站,每一个变量都需要储存到指定的命名空间当中
命名空间实际上就是一个字典,是一个专门用来储存变量的字典
locals()用来获取当前作用域的命名空间
如果在全局作用域中调用locals()则获取全局命名空间,返回一个字典
如果在函数作用域中调用locals()则获取函数命名空间,返回一个字典
a= 1000
scope =locals()
print(scope["a"])
def fn():
a = 100
scope = locals() # 函数内部的命名空间
return print(scope["a"])
fn()
递归
创建一个函数,可以用来求任意数的阶乘
n = 10
for i in range(1,10):
n *= i
print(n)
函数:
def sum(x):
n = x
for i in range(1, x):
n *= i
return n
print(sum(10))
递归的函数
递归式函数,在函数中自己调用自己
def fn():
fn() # 死循环递归,一旦调用,内存会挤满
递归式函数的二个要件:
1.基线条件时
- 问题可以被分解为的最小问题,当满足基线条件时,递归就不会执行
2.递归条件
- 将问题继续分解的条件
def fn(x):
'''
该函数用来求任意数的阶乘
参数:
x 要求阶乘是一个数字
'''
if x == 1: # 1的基乘就是1
return 1 # 返回1
return x * fn(x-1) # 递归条件
print(fn(10))
练习1:
创建一个函数power来为任意数字做幂运算 n ** i
def power(n, i):
'''
参数:
n:要做幂运算的数字
i:做幂运算的次数
'''
if i == 1: #基线条件
return n # 求1次幂
return n * power(n, i-1) # 递归条件
print(power(2,2))
练习2:
创建一个函数,来检查一个任意的字符串是否是回文字符串,如果是返回True, 否则返回False
如(abcba)这个就是一个回文
def hui_wen(s):
'''
参数:
s:就是要检查的字符串
'''
if len(s) < 2: # 基数条件,字符串的长度小于2,则字符串一定是回文
return True
elif s[0] != s[-1]:
return False
return hui_wen(s[1:-1])
print(hui_wen("abcba"))
print(hui_wen("abcda"))