函数
文章目录
提示:以下是本篇文章正文内容,下面案例可供参考
一、函数基础
1.参数
形参:
实参:
1.默认参数:默认参数就是在函数定义时,给参数一个默认值。调用该函数时可以不给有默认值的参数传值,这样调用时的参数可以减少。
def say_hi(name, greeting='Hi', more=''):
print(greeting, name, more)
这个函数有三个参数,其中greeting和more有默认值
提示:所有的默认参数必须放在非默认参数之后,下图默认参数放a放在了非默认参数之前会报错、。
2.关键字参数:调用函数时,我们可以使用“关键字参数”,它的形式是:kwarg=value。
提示:关键字参数必须放在位置参数之后
3.不定长参数:‘*’只能接收位置参数,‘**’只能接收关键字参数
2.拆分参数列表
如果一个函数所需要的参数存储在列表、元组或字典中,就可以直接从列表、元组或字典中拆分出函数所需要的参数,其中列表、元组拆分出来的结果作为位置参数,而字典拆分出来的结果作为关键字参数
列表 内联代码片
。
def SumVal(*args): # 定义函数SumVal
sum = 0
for i in args:
sum += i
print('求和结果是', sum)
ls = [3, 5.2, 7, 1]
SumVal(*ls)
代码中*ls的作用是把列表ls中的所有元素拆分出来作为SumVal的实参,
即等价于SumVal(3,5.2,7,1)
字典 内联代码片
。
def StudentInfo(name, chineselevel, country): # 定义函数StudentInfo
print('姓名: % s, 中文水平: % s, 国家: % s' % (name, chineselevel, country))
d = {'country':'中国', 'chineselevel':'良好','name':'李晓明'}
StudentInfo(**d)
# ** d的作用是把字典d中的所有元素拆分出来作为StudentInfo的实参,即等价于
# StudentInfo(name=“李晓明”, chineeselevel =“良好”, country =“中国”)
# 姓名: 李晓明, 中文水平: 良好, 国家: 中国
3.参数传递
位置传递
地址传递
def avgScore(a, b, c):
avg = (a + b) / 2
if avg > c:
print("成绩高于平均分")
else:
print("成绩低于平均分")
# 1) 按位置传递
# avgScore(90,85,79)
# 成绩高于平均分;
# 2)按名称传递
# avgScore(c=79,a=90,b=85)
# 成绩高于平均分;
传对象引用
如果函数收到的是一个可变对象(比如字典或者列表)的引用,就能修改对象的原始值——相当于传地址。如果函数收到的是一个不可变对象(比如数字、字符或者元组)的引用,就不能直接修改原始对象——相当于传值。
传值示例
def a(n): #定义了一个带有参数的函数
n += 100 #主要实现 +100的操作并输出n的值
print(n)
an=5 #现有一个变量
print(an)
a(an)
print(an)
# #运行结果:
# 5 105 5
传地址示例
def b(n): #定义了一个带有参数的函数b
n[2] = 300
print(n)
bn = [1,5,6,5,7,9] #长度为6的列表
print(bn)
b(bn)
print(bn)
# #运行结果:
[1, 5, 6, 5, 7, 9]
[1, 5, 300, 5, 7, 9]
[1, 5, 300, 5, 7, 9]
4.函数返回值
return表示返回,后面的代码不会执行
下面展示一些 内联代码片
。
def avgScore(a, b, c):
sum = a + b + c
avg = sum / 3
maxScore = max(a, b, c)
minScore = min(a, b, c)
return sum, avg, maxScore , minScore
a,b,c,d =avgScore(80,91,93)
print(a)
print(b)
print(c)
print(d)
# 运行结果如为264、88.0、93、80。
x=avgScore(80,91,93)
print(x)
# 运行结果为长度为4的一个元组,(264, 88.0, 93, 80)。
5.变量的作用域
局部变量
定义在函数内的变量,其作用域是从定义域局部变量位置开始,一直到函数结束的位置,当函数执行结束之后,局部变量自动删除,不可使用。
全局变量
定义在函数外的变量,在所有的函数中可以使用,如果需要在一个函数内部给一个全局变量赋值,需要使用global关键字来声明
下面展示一些 内联代码片
。
a = 60 #定义全局变量a,a为软件工程1班学生人数
def count1( ):
global a # 在函数内部用global声明全局变量a
print("软件工程1班人数为:"+str(a))
def count2 ( ):
global a #在函数内部用global声明全局变量a
b=65 #在函数内部定义局部变量b,b为软件工程2班学生人数
a = a + b
print('软件工程1班和2班总人数为:'+ str(a))
count1( )
count2( )
print(a)#a的值变为125
#运行结果
#软件工程1班人数为:60
#软件工程1班和2班总人数为:125
#125
nonlocal关键字
当函数嵌套函数的时候,如果内层函数想要修改外层函数的值,可以使用nonlocal关键字。
def count():
a = 60
def count2():
nonlocal a
b = 65
a = a + b
return a
return count2()
a = count()
print('软件工程1班和2班总人数为:'+str(a))
#软件工程1班和2班总人数为:125
如果没有带括号如下图
## 6.模块
Python提供了两种运行方式:**交互式,脚本式**。当要执行的代码比较长且需要重复使用的时候,我们通常将代码放在扩展名为.py的Python脚本文件中。这些脚本文件就是模块。
### 模块导入
使用import关键字导入
```javascript
import math as m #导入math模块并起别名m
import sys, time #一次导入sys,time两个模块
也可以使用from导入模块中指定的对象
# from 模块名 import 导入对象名 #导入模块中某个对象
# 也可以为导入的对象起别名,语法为:
# from 模块名 import 导入对象名as别名 #给导入的对象指定别名
# 如果想导入模块中所有对象 ,可以定义为:
# from 模块名 import *
# 注意:使用from导入的对象可以直接使用,不需要使用模块名作为限定符。
7.包
包和库都是比“模块”大的,一般来讲一个包会有许多模块,二库是一个更大的概念,比如python标准库中每个库都有好多个包,每个包有若干个模块。
一个包由多个模块组成,即有多个.py的文件,那么这个所谓的“包”就是我们熟悉的一个目录罢了。现在需要解决如何引用某个目录中的模块问题。解决方法就是在该目录中放一个__init__.py文件。 init.py是一个空文件,将它放在某个目录中,就可以将该目录中的其他.py文件作为模块被引用。
提示:init.py可以是一个空文件,也可以包含包的初始化代码或者设置__all__列表。
8.猴子补丁
指的是在运行的时候动态替换已有的代码。
猴子补丁主要用于在不修改已有代码情况下修改其功能或增加新功能的支持
下面展示一些 内联代码片
。
def Sum(a,b): #定义函数Sum
print('‘Sum函数被调用!’') #通过输出信息可以知道哪个函数被调用
return a+b #将a和b的求和结果返回
def NewSum(*args): #定义函数NewSum
print('NewSum函数被调用!') #通过输出信息以知道哪个函数被调用
s=0 #s用于保存求和结果,初始赋为0
for i in args: #i取传入的每一个参数值
s+=i #将i加到s上
return s #将保存求和结果的s返回
Sum=NewSum #将NewSum赋给Sum,后面再调用Sum函数,实际上就是执行NewSum函数
print(Sum(1,2,3,4,5)) #调用Sum函数(实际是执行NewSum)计算1至5 的和并输出
9.python标准库的应用
1.random模块
random模块用于生成随机数,其中常用的函数有random(),randint()等。
random()函数返回一个0到1之间的随机浮点数你(0<=n<1)
random.randint(1,10)返回一个1到10之间的随机整数(不包括10)
2.time模块
time模块用于获取时间并处理,有两种时间表示方式。
1.时间戳
时间戳是指从格林尼治时间1970年01月01日00时00分00秒起至现在的总秒数。time模块中的time()函数可以获取当前的时间戳
下面展示一些 内联代码片
。
import time
print(time.time())
1640776021.1630063
很显然我们不能获取具体的时间,那么我们可以将其转换成时间元组来获取具体时间
2.时间元组
时间元组struct_time包含9个元素
在time模块中,localtime()函数可以讲一个时间戳转换为一个当前时区的元组。
import time
print(time.time())
print(time.localtime(time.time()))
time.struct_time(tm_year=2021, tm_mon=12, tm_mday=29, tm_hour=19, tm_min=11, tm_sec=13, tm_wday=2, tm_yday=363, tm_isdst=0)
从运行结果来看我们也不易观察,所以我们可以通过strftime()函数将时间元组格式化
import time
print(time.time())
print(time.localtime(time.time()))
print(time.strftime("%Y-%m-%d %H:%M %S",time.localtime(time.time())))
#
2021-13-29 19:13 18
二、高阶函数
1.高阶函数
高阶函数是指把函数作为参数的一种函数
下面展示一些 内联代码片
。
def FunAdd(f,x,y):
return f(x)+f(y)
def Square(x):
return x**2
def Cube(x):
return x**3
print(FunAdd(Square,3,-5))#调用函数FunAdd,计算32+(-5)2
print(FunAdd(Cube,3,-5)) #调用函数FunAdd,计算33+(-5)3
#注
34
-98
2.lambda函数
lambda函数也可以叫匿名函数,因为lambda函数的函数体是一个表达式,所以lambda函数只能实现简单的功能
下面展示一些 内联代码片
。
def FunAdd(f,x,y):
return f(x)+f(y)
print(FunAdd(lambda x:x**2,3,-5))
print(FunAdd(lambda x:x**3,3,-5))
34
-98
3.闭包
什么叫闭包?
如果一个内层函数使用了外层函数中定义的局部变量,并且外层函数的返回时是内层函数的引用,这样就构成了闭包。
定义在外层函数中但是由内层函数使用的变量成为自由变量
一般情况下,如果一个函数结束,那么该函数中定义的局部变量就都会被释放。
下面展示一些 内联代码片
。
def outer(x):#定义函数outer
y=10#定义局部变量y并赋值10
def inner(z):#定义内层函数
nonlocal x,y#nonlocal关键字声明使用外层函数中的局部变量
return x+y+z
return inner #返回嵌套函数inner的引用(***注意:不带括号***)
f=outer(5)
g=outer(50)
print('f(20)的值为:', f(20))
print('g(20)的值为:', g(20))
// A code block
var foo = 'bar';
4.装饰器
什么事装饰器呢?
利用装饰器,可以在不修改已有函数的情况下向已有函数中注入代码,使其具备新的功能。
一个装饰器可以为多个函数注入代码,一个函数也可以注入多个装饰器的代码。
下面展示一些 内联代码片
。
def deco1(func):#传入的参数func是将要被装饰的函数
def inner1(*args,**kwargs):#*args,**kwargs代表可以传入任意个数的参数
print('deco1 begin')
func(*args,**kwargs)#*args,**kwargs代表可以传入任意个数的参数
print('deco1 end')
return inner1 #返回函数inner1的引用
def deco2(func):
def inner2(*args,**kwargs):
print('deco2 begin')
func(*args,**kwargs)
print('deco2 end')
return inner2
@deco1 #装饰器deco1 修饰函数f1
def f1():
print("hahaha")
@deco1
@deco2
def f2():
print("lalala")
f1()
f2()
运行结果:
deco1 begin
hahaha
deco1 end
deco1 begin
deco2 begin
lalala
deco2 end
deco1 end