python 函数
一:函数的定义与调用
1.1 什么是函数
函数时组织好的,可重复使用的,用来实现单一或相关联的功能的代码段,它能够提高应用的规模和代码块的重复利用率.
1.2 定义函数
python 中使用def 关键字定义函数,格式如下:
""""
def 函数名(参数列表):
"函数_文档字符串"
函数体
return 表达式
"""
def add(a,b):
sum = a + b
return sum
1.3 调用函数
定义函数之后,想要让这些代码能够执行,需要调用函数.
通过 函数名() 即可调用函数
def add(a,b):
sum = a + b
return sum
d = add(1,2)
print(d)
调用同文件的函数,只需要在函数下方写函数名,传对应参数即可调用
调用不同文件的函数,需要先导入: from 文件路径 import 函数名(或者*)
二: 函数的参数
2.1 函数的参数传递
如果希望定义的函数可以计算任意两个数的和,我们在定义函数的时候,让函数接收数据.
这就是函数的参数
# 带参函数
def add(a,b): # a,b 被称之为形式参数,形参
print(a+b)
# 10,30 ; "abc","def" 被称之为实际参数,实参
add(10,30)
add("abc","def")
2.2 默认参数
调用函数时,若默认参数未被传值,则会使用参数的默认值;
若默认参数被传入了值,则会使用传入的新值
定义函数时,可以给函数的参数指定默认值,这个被指定默认值的参数就被称为默认参数
带有默认值的参数一定要位于参数列表的末尾.否则程序会报错
# 演示参数默认值
def add(a, b=3):
print(a+b)
# 值传递了参数a,没有传递给b,所以b使用默认值
add(a=11)
# 传递了值给b,b使用传递的值
add(a=22,b=33)
# 输出结果
14
55
有默认的参数,可以不赋值,直接使用默认值
如果对有默认值的参数赋值,则该参数的值为新值
无默认值的参数不可以定义在有默认值的参数之后
2.3 不定长参数
若希望函数被调用时能够传入比定义时更多的参数,可以在定义函数时使用不定长参数
加* 的参数,会以元祖的形式存放未命名的参数
加**的参数,会以字典的形式存放未命名的参数。即以key = value的参数
2.3.1 元组形式的不定长参数
"""
def 函数名([formal_args,]*args,**kwargs):
"函数_文档字符串"
函数体、
return 表达式
"""
# 加* 的参数 *args,会以元祖的形式存放未命名的参数
def test1(a, b, *args):
print(a)
print(b)
print(args)
# 没有给不定长参数赋值,会显示空元组
test1(11, 22)
print("------")
#给不定长参数赋值,则会元组形式,存放多个值
test1(11, 22, 33, 44, 55)
# 输出结果:
11
22
()
------
11
22
(33, 44, 55)
2.3.2 字典形式不定长参数
#以 **kwargs格式的不定长参数会以字典形式存放命名的参数
def test1(**kwargs):
print(kwargs)
#赋值时,需要以key=value 形式赋值
test1(a=1, b=2, c=3)
#输出结果:
{'a': 1, 'b': 2, 'c': 3}
如果是多个可变参,如*a,*b 则报错重复的可变参
如果把可变参放前面,传参的时候必须指定
一般,可变长度的参数写在不可变参数的后面
2.4 集合类型的地址作为值
集合类型的地址,就是变量的值,只要地址不变,地址内元素怎么改变
def add(a):
for x in range(len(a)):
a[x] += 10
lst = [10, 20, 30]
add(lst)
print(lst)
# 输出结果:
[20, 30, 40]
三:函数的返回值
3.1 定义函数的返回值
python 中使用return语句返回结果.在函数有了返回值之后,我们可以使用变量接受函数返回值,或者使用print打印
def add(a, b):
sum = a + b
return sum
# 先使用变量接受返回值,在打印变量
result = add(10, 20)
print(result)
# 直接打印
print(add(90, 100))
# 输出结果
30
190
3.2 函数的四种类型
根据函数的参数和返回值,函数可以分为四种类型
- 无参数,无返回值函数
- 无参数,有返回值函数
- 有参数,无返回值函数
- 有参数,有返回值函数
3.2.1 无参数,无返回值函数
def menu():
print("-------")
print("小当家大排档菜单")
print("西红柿炒鸡蛋")
print("宫保鸡丁")
print("红烧排骨")
print("-------")
menu()
# 输出结果:
-------
小当家大排档菜单
西红柿炒鸡蛋
宫保鸡丁
红烧排骨
-------
3.2.2 无参数,有返回值的函数
def temperature():
return 24
result = temperature()
print("当前温度为:",result)
# 输出结果:
当前温度为: 24
3.2.3 有参数,无返回值的函数
def add(a, b):
sum = a + b
print("结果为:", sum)
add(10, 20)
#输出结果:
结果为: 30
3.2.4 有参数,有返回值的函数
def count_add(num):
sum = 0
for i in range(num+1):
sum += i
return sum # 使用结果作为返回值
n = int(input("请输入一个整数:"))
#使用一个变量接收函数返回值
result = count_add(n)
print("从0加到%i的和是" %n, result)
# 输出结果:
请输入一个整数:100
从0加到100的和是 5050
四:函数的嵌套调用
# 演示函数的嵌套调用
def func_one():
print("----func_one start----")
print("这里是func_one函数执行代码")
print("----func_one end----")
def func_two():
print("----func_two start----")
func_one() #在函数func_two中调用函数func_one
print("----func_two end----")
func_two()
# 输出结果:
----func_two start----
----func_one start----
这里是func_one函数执行代码
----func_one end----
----func_two end----
五: 变量的作用域
5.1: LEGB原则
- python中,程序的变量并不是在哪个位置都可以访问的,访问权限决定于这个变量是在哪里赋值的.
- 变量的作用域决定了在哪一部分程序可以访问哪个特定的变量名称.
- python 的作用域一共有四种:
- L (Local):函数内的区域,包括局部变量和参数
- E (Enclosiong): 外面嵌套函数区域,常见的是闭包函数的外层函数
- G (Global): 全局作用域.
- B (Built-in) :内建作用域
- python中变量是按照 L ---> E ---> G ---> B 的顺序查找的
- python在查找变量的时候会优先取函数内作用域中查找,若没有找到便会到嵌套函数作用域中查找,再找不到就去全局作用域中查找,最后再去内建作用域中查找
局部变量
- 所谓局部变量,就是在函数内部定义的变量
- 局部变量的作用域是函数内部,说明它旨在定义它的函数中有效,一旦函数结束就会消失
全局变量
- 定义在函数外的变量拥有全局作用域
- 全局变量可以在整个程序范围内访问.
- 如果出现全局变量和局部变量名字相同的情况,则在函数中有限访问局部变量
# 这是全局变量a
a = 10
def test():
# 这是定义在函数内部的变量a.它只能作用在函数内部
a = 20
# 所以,在print 变量a的值时,会先去函数内作用域查找
print("a的值是:", a)
test()
# 这里不在函数内部,因此函数内的变量a不起作用.回去找全局变量a
print("a的值is:", a)
# 输出结果:
a的值是: 20
a的值is: 10
5.2 global和nonlocal关键字
5.2.1 global关键字
global关键字用来在函数或者其他局部作用域中使用全局变量
a = 100
def test():
global a
a += 100
print(a)
test()
# 输出结果
200
5.2.2 nonlocal关键字
nonlocal 是 python 内置的关键字,其作用是可以在内层函数内声明一个外部函数的变量,它的功能与global 相似,nonlocal 本质上是介于 全局作用域和局部作用域之间的,它仅在函数的嵌套使用时才起作用。
def func_one():
count = 1
def func_two():
nonlocal count
count = 12
func_two()
print(count)
func_one()
# 输出结果:
12
六: 递归函数与匿名函数
6.1 递归 函数
一个函数内部可以调用其他函数.但是如果一个函数子啊内部不是调用其他函数,而是调用自己本身的话,这个函数就是递归函数
# 演示递归函数
b = 0
def a(b):
b += 1
if b <= 3:
print("第%i次调用开始" % b)
a(b)
print("第%i次调用结束" % b)
a(b)
# 输出
"""
第1次调用开始
第2次调用开始
第3次调用开始
第4次调用结束
第3次调用结束
第2次调用结束
第1次调用结束
"""
def jiecheng(n):
# 1 的阶乘结果就是1
if n == 1:
# 使用return 返回结果.
return n
else:
# 使用return返回结果,使其可以被调用.
# 让n -1 ,使得n 的值不断减小
return n * jiecheng(n - 1)
num = int(input("请输入一个整数:"))
result = jiecheng(num)
print("%s的阶乘是:" % num, result)
#输出结果:
请输入一个整数:5
5的阶乘是: 120
#整个代码运行过程是:
"""
jiecheng(5)
==>5 * jiecheng(4)
==>5 * (4 * jiecheng(3))
==>5 * (4 * (3 jiecheng(2)))
==>5 * (4 * (3 * (2 * jiecheng(1))))
==>5 * (4 * (3 * (2 * 1)))
==>5 * (4 * (3 * 2))
==>5 * (4 * 6)
==>5 * 24
==>120
"""
# 使用递归实现阶乘计算
def jiecheng(num, result):
# result 获取乘积.开始,result值为"输入的数乘以num 乘以 1"
result *= num
# 每次被调用,num值-1,当值大于等于时,就继续调用函数.
# 效果为每次都是上一轮累计的result*num的乘积,在乘以num值
num -= 1
if num >= 1:
jiecheng(num, result)
# 当值等于0时,就不在调用,而是输出print语句
if num == 0:
print(n,"的阶乘是:",result)
n = int(input("请输入一个整数:"))
a = 1
jiecheng(n, a)
# 输出结果:
请输入一个整数:5
5 的阶乘是: 120
#计算过程:
"""
jiecheng(5,1)
result = 5 * 1 =5 ;num = 5 -1 =4
===>
jiecheng(4,5)
result = 5 * 4 =20; num = 4 -1 =3
===>
jiecheng(3,20)
result = 20 * 3 =60; num = 3 -1 =2
===>
jiecheng(2,60)
result = 60 * 2 =120; num = 2 -1 =1
===>
jiecheng(1, 120)
result = 120 * 1 =120; num = 1 -1 =0
===> num =0
n = 5,result=120
print("5的阶乘是120")
"""
# 使用递归实现阶乘计算
result = 1
def jiecheng(num):
global result
result *= num
num -= 1
if num >= 1:
jiecheng(num)
n = int(input("请输入一个整数:"))
jiecheng(n)
print(n, "的阶乘是:", result)
6.2 匿名函数
匿名函数就是没有名称的函数,也就是不再使用def语句定义的函数.
如果要定义匿名函数,则需要使用lambda关键字.
- lambda [arg1 [,arg2,....argn]]:expression
# 演示匿名函数
result = lambda a, b: a + b
print("运行结果:", result(10, 20))
print("运行结果:", result(20, 20))
# 输出结果:
运行结果: 30
运行结果: 40
匿名函数与普通函数的区别:
- 普通函数在定义时有名称,而匿名函数没有
- 普通函数的函数体中包含有多条语句,而匿名函数的函数体只能是一个表达式
- 普通函数可以实现比较复杂的功能,而匿名函数课实现的功能比较简单
七 时间和日期函数
7.1 时间函数
在python 中,通常由如下几种方式表示时间
- 时间戳
- 格式化的时间字符串
- 时间元组(struct_time
7.1.1 时间戳
时间戳表示从1970年1月1日00:00:00 开始按秒计算的偏移量
import time #引入时间模块
ticks = time.time()
print("当前时间戳为:",ticks)
#
当前时间戳为: 1642693762.2411685
7.1.2 格式化时间字符串
我们可以使用time模块的strftime 方法来格式化日期.
import time
print(time.strftime("%Y-%m-%d %H:%M:%S",time.localtime()))
格式化符号 | 含义 |
---|---|
%y | 两位数的年份表示(00~99) |
%Y | 四位数的年份表示(000~9999) |
%m | 月份(01~12) |
%d | 月内中的一天 |
%H | 24小时制小时数(0~23) |
%l | 12小时制小时数(01~12) |
%M | 分钟数(00~59) |
%S | 秒(00~59) |
7.1.3时间元组
返回时间元组的函数主要有gmtime(),localtime() 和strptime(). 时间元组共有9个字段
序号 | 字段 | 值 |
---|---|---|
0 | tm_year | 2008 |
1 | tm_mon | 1到12 |
2 | tm_mday | 1到31 |
3 | tm_hour | 0到23 |
4 | tm_min | 0到59 |
5 | tm_sec | 0到61 |
6 | tm_wday | 0到6 |
7 | tm_yday | 1到366 |
8 | tm_isdst | -1,0,1,-1是决定是否为夏令时的旗帜 |
- time.altzone
- 返回格林威治西部的夏令时地区的偏移秒数。如果该地区在格林威治东部会返回负值(如西欧,包括英国)。对夏令时启用地区才能使用。
- time.asctime([tupletime])
- 接受时间元组并返回一个形式为"Tue Dec 11 18:07:14 2008"(2008年12月11日 周二18时07分14秒)的24个字符的字符串。
- time.clock( )3.8版本淘汰 time.process_time()
- 用以浮点数计算的秒数返回当前的CPU时间。用来衡量不同程序的耗时,比time.time()更有用
- time.ctime([secs])
- 作用相当于asctime(localtime(secs)),未传入secs参数相当于asctime()。
- time.gmtime([secs])
- 接收时间辍(1970年1月1日00:00:00后经过的浮点秒数)并返回格林威治天文时间下的时间元组
- time.localtime([secs])
- 接收时间辍( 1970年1月1日00:00:00后经过的浮点秒数)并返回当地时间下的时间元组。
- time.mktime(tupletime)
- 接受时间元组并返回时间辍。
- time.sleep(secs)
- 推迟调用线程的运行,secs指秒数。
- time.strftime(fmt[,tupletime])
- 接收时间元组并返回以可读字符串表示的当地时间,格式由fmt决定。
- time.strptime(str,fmt='%a %b %d %H:%M:%S %Y')
- 根据fmt的格式把一个时间字符串解析为时间元组。
- time.time( )
- 返回当前时间的时间戳。
- time.tzset()
- 根据环境变量TZ重新初始化时间相关设置。
- time.timezone
- 表示当地时区(未启动夏令时)距离格林威治的偏移秒数(>0,美洲;<=0大部分欧洲,亚洲,非洲)
- time.tzname
- 包含一对根据情况不同而不同的字符串,分别是带夏令时的本地时区名称,和不带名称的。
7.2 日历函数
- calendar.calendar(year,w=2,l=1,c=6)
- 返回一个多行字符串格式的year年年历,3个月一行,间隔距离为c。每日宽度间隔为w个字符。每行长度为21* W+18+2* C。l是每星期行数。
- calendar. firstweekday()
- 返回当前每周起始日期的设置。默认情况下,首次载入calendar模块时返回0,即星期一。
- calendar.isleap(year)
- 如果是闰年返回True,否则为False。
- calendar.leapdays(y1,y2)
- 返回Y1、Y2两年之间的闰年总数。
- calendar.month(year,month,w=2,l=1)
- 返回一个多行字符串格式的year年month月日历,两行标题,一周一行。每日宽度间隔为w字符。每行的长度为7* w+6。l是每星期的行数
- calendar.monthcalendar(year,month)
- 返回一个整数嵌套列表。每个子列表装载代表一个星期的整数。year年month月外的日期都设为0;范围内的日期都使用该月第几日表示,从1开始。
- calendar.monthrange(year,month)
- 返回两个整数,第一个整数是该月星期几的日期码,第二个整数是该月的日期码。日从0(星期一)到6(星期日);月从1到12。
- calendar.prcal(year,w=2,l=1,c=6)
- 相当于print(calendar.calendar(year,w,l,c))
- calendar.setfirstweekday(weekday)
- 设置每周的起始日期码。日期码的范围为0(星期一)~6(星期日)
- calendar.prmonth(year,month,w=2,l=1)
- 相当于print(calendar.calendar(year,w,l,c))
- calendar.timegm(tupletime)
- 接受一个时间元组,返回该时刻的时间辍(1970纪元后经过的浮点秒数)
- calendar.weekday(year,month,day)
- 返回给定日期的日期码。星期为0(星期一)~6(星期日);月份为 1(1月)~ 12(12月)。
八 随机函数
8.1 random.random()
用于生成一个0到1的随机符点数N:0 <= N < 1.0。
import random # 导入模块
print("random():",random.random())
#输出结果:
random(): 0.93203272738572
8.2 random.uniform(a,b)
返回a、b之间的随机浮点数,范围为[a,b] 。
import random # 导入模块
print("random:",random.uniform(50,100))
#输出结果:
random: 57.08371353402669
8.3 random.randint(a,b)
返回a、b之间的随机整数N,N的取值范围为a<=N<=b,且a一定要小于b。
import random # 导入模块
for i in range(5):
print(random.randint(10,20))
# 输出结果:
20
19
15
20
12
8.4 random.randrang([start], stop[, step])
返回指定递增基数集合中的一个随机数,基数默认值为1。其中,start参数用于指定范围的开始值,其包含在范围内;end参数用于指定范围的结束值,其不包含在范围内;step表示递增基数。
import random # 导入模块
for i in range(5):
print(random.randrange(10, 20, 2))
#输出结果:
12
10
18
18
16
8.5 random.choice(sequence)
从sequence中返回一个随机元素。 sequence可以是列表、元组、字符串。
import random # 导入模块
a = [1, 2, 3, 4, 5, 6]
for i in range(3):
print(random.choice(a))
# 输出结果:
3
2
6
8.6 random.shuffle(x[,random])
将列表中的元素打乱顺序,俗称为洗牌。
import random # 导入模块
a = [1, 2, 3, 4, 5, 6]
random.shuffle(a)
print(a)
#输出结果:
[5, 1, 6, 3, 2, 4]
8.7 random.sample(sequence,k)
从指定序列中随机获取k个元素作为一个片段返回,sample函数不会修改原有序列 。
import random # 导入模块
a = [1, 2, 3, 4, 5, 6]
result = random.sample(a, 2)
print(result)
print(a)
# 输出结果:
[4, 3]
[1, 2, 3, 4, 5, 6]