函数
函数是一个独立功能的代码块,通过代替多次出现的功能,提高编写代码的效率
为什么要使用函数?代码的复用(反复使用)最大化以及最小化冗余代码,整体代码结构清晰,问题局部化
内置函数
python
中有许多可以直接调用的函数,这些函数叫做内置函数
运算类的内置函数如:
max
函数,min
函数判断类的内置函数如:
or
函数,any
函数io
操作类的内置函数:input
函数,print
函数编码类的转换:
ord()
返回Unicode字符对应的整数chr()
返回整数对应的Unicode字符bin()
将整数转化为2进制字符串oct()
将整数转化为8进制数字符串hex()
将整数转化为16进制字符串
python# int()函数:基本格式:int(x[,base=10]) int("35",8) = 29 # 八进制 # ord()函数: ord('a') # ASCLL码 97 ord('中') # 汉字‘中’的Unicode码 20013 # chr()函数: chr(97) # 'a'
转换类的内置函数:
bool()
根据传入的参数逻辑值创建一个新的布尔值int()
根据传入的参数创建一个新的整数float()
根据传入的参数创建一个新的浮点数complex()
根据传入的参数创建一个新的复数str()
创建一个字符串
创建新的列表的函数:
list()
根据传入的参数创建一个新的列表type()
函数:type(a)
查看a
的数据类型:显示结果为class'str'
表示a为字符串,显示结果为class'int'
表示a为整形del()
函数:del(sum)
当sum
被赋值时,要重新用回sum
函数的功能,用del()
函数恢复。所以不要用python
的内置函数进行赋值id()
函数:可以显示对象的地址,python
会将-5到256存放在一个小整数,在对象池中,这样不用对重新对这些对象去进行内存的分配,从而提高效率。所以
a=1 b=1 id(a)=id(b)=id(1)
a=1000 b=1000 id(a)!=id(b)!=id(1000)
但是如果
a=b=1000
,这样分配的地址是一样的,所以id(a)=id(b)
sorted
函数:对字符串,列表,元组,字典等对象进行排序操作,sort
是应用在list
上的方法,sorted
可以对更多的数据类型进行排序操作,sort
是对存在的列表进行操作,而sorted
返回一个新的list
,不是在原来的基础上进行操作语法:
sorted(iterable,key,reverse)
iterable
-- 序列,如字符串,列表,元组等。key
-- 函数,缺少为空。reverse
-- 排序规则reverse = True
降序reverse = False
升序(默认)
map
函数:根据提供的函数对指定序列做映射语法:
map(function,iterable,...)
function
-- 是对参数序列中的每一个元素调用function
函数,iterable
是序列print(list(map(lambda x:x**2,[1,2,3,4,5])))
得到{1,4,9,16,25}
一一映射使用zip
函数:将对象中对应的元素打包成一个元组,然后返回这些元组。如果元素长度不一致,则返回列表长度与最短的对象相同pythona = [1,2,3] b = [4,5,6] c = [4,5,6,7,8] print(list(zip(a,b))) # 得到:[(1,4),(2,5),(3,6)] print(list(zip(a,c))) # 得到:[(1,4),(2,5),(3,6)] 多出来的丢掉了
all
函数和any
函数all
函数参数都是True
,就返回True
,否则返回False
any
函数参数只要有一个为True
,就返回True
,全部为False
时,返回False
自定义函数
自定义函数的定义语法格式:函数要先定义在调用
def 函数名(参数表):
函数体
参数表中的参数个数可以是零个,也可以是多个,是根据具体的场景而定的
函数调用是指将一组特定数据传递给被调用函数,然后启动函数体的执行,最后返回到主程序中的调用点并带回返回值的过程。调用方法:func_name(par1,par2,…)
函数的备注说明信息一般加在函数体上方,方便其他人熟悉函数,备注信息一般是用多行注释去添加
函数的参数
参数:函数为了实现某项特点的功能,进而为了得到实现功能所需要的外部数据
形参(定义时):形参只是意义上的一种参数,函数定义时的参数,像变量一样,定义的时不占内存地址
形参指的是函数定义时函数名后面括号里的参数,多个形参用逗号“,”分隔,这些形参用于接收函数调用时传入的具体数据,其作用域为该函数局部
实参(调用时):调用函数时,函数中的参数值为实参,实参是占用内存地址的
实参是在函数调用时函数名后圆括号中的参数,用于给形参传递具体的值在函数调用时,实参和形参要一一对应,包括参数个数的对应、参数类型的对应,否则将会导致错误
当参数是数值类型、字符串类型和布尔类型、元组时,形参的改变不会影响实参,这样的数据类型称为不可变数据类型。当参数是列表、字典时,形参的改变意味着实参的改变,这样的数据类型称为可变数据类型。当实参是不可变对象时,形参值改变不会影响实参。当实参是可变对象,形参值改变可能会影响实参。赋值是不可变对象,列表是按照地址来寻址的,是可变的
参数类型
位置参数(必选参数)
传入参数的值按照顺序依次赋值给形参,在调用的时候,必选参数必须要一一对应的赋值
关键字参数
调用参数时可以指定对应形式参数的名字
关键字实参对于实参的位置没有要求,关键字参数在函数调用时实参采用“形参名=实参”的格式,明确将实参值传递给某个形参,实现一种显式的参数匹配效果,从而摆脱位置的约束
位置参数和关键词参数同时使用,先写位置参数,再写关键字参数,如:dis(1,2,y2=5,x2=4)
调用时:funcname([位置参数],[关键字参数])
默认值参数(缺省参数)
当调用方没有提供形参的值时,你可以指定默认形式参数值,如果你提供实参,在调用时会代替默认值
def power(x,n = 2):
.....
power(5) # 函数调用时,只有一个实参5,那么将5传递给第一个形参x,第二个形参采用默认值2
# 函数调用时,有两个实参:4和3,那么将4传递给第一个形参x,3传递给第二个形n,此时默认参数采用传递过来的实参值3
power(4,3)
注意事项:默认参数只能出现在参数列表的最后,其后面不能出现非默认参数
数量可变参数(不定长参数)
一个星号*:当函数参数数目不确定时,星号将一组可变数量的位置参数集合成参数值的元组
def func(a, b, *c):
print("a:",a)
print("b:",b)
print("c:",c)
func(1,2,3,4,5)
# 得到:
# a: 1
# b: 2
# c: (3, 4, 5)
func(1,2)
# 得到:
# a: 1
# b: 2
# c: ()
两个星号**:收集参数到字典中,该参数类型又叫关键字可变参数
def count(a,**d):
print(d)
count(3,x1 = 9,x2 = 1,x3 = 6)
# 得到:{'x1':9,'x2':1,'x3':6}
# 另外一种参数传递方式
dictA = {"x1":3, "x2":1, "x3":6}
count(**dictA)
可选参数接受的数据是一个元组类型;关键字可变参数接受的数据是一个字段类型
当在函数定义时可以既包括元组变长参数,也包括字典变长参数,其一般格式如下:
关键字可变参数必须在数量可变参数的后面,否则会报错
def func_name(formal_args,*args,**kwargs):
statements
return expression
函数的返回值
返回值就是程序中函数完成一件事情后,最后给调用者返回的一个结果,用return
语句返回值
return
后面的表达式的值就成为这次函数调用的返回值
如果没有return
语句返回,函数返回None
,None
是一个特殊值,不表示任何数据,但有重要作用,返回值可以返回数字,还可以返回函数
partial
函数
在普通函数执行时,要带上必要的参数进行调用,partial
函数在调用时参数提前获知,有些参数就预先可以用上,使函数能用更少的参数进行调用。
在函数执行时,要先导入functools
模块:
import functools
def add(a, b):
return a + b
rst1 = add(4, 2)
plus3 = functools.partial(add, 3)
rst2 = plus3(4)
# 结果 rst1 = 6 rst2 = 7
partial
函数定义了一个匿名函数。
partial
函数不会提高效率,但是会使代码更加简洁
Lambda
函数
函数的另外定义方法:lambda
表达式;它定义了一个匿名函数。用来编写简单的函数,如:
g = lambda x,y,z:x+y+z
add = lambda a,b:a+b
print(add(3,4))
# 还可以这样使用:
print((lambda a,b:a+b)(3,4))
变量的作用域
命名空间和作用域:变量可被访问的范围为变量的作用域,也称变量命名空间,每一个函数定义自己的命名空间,函数内部定义的变量为局部变量。python解释器建立一个全局命名空间,全局变量就放在这个空间。
- 全局变量:定义在函数外,作用域为整个程序
- 局部变量:定义在函数内,作用域为函数内部,形参也是局部变量
global
关键字:函数调用不能修改全局变量
num1 = 6
def fun1():
num1 = 2
print("函数内修改后num1=", num1)
print("运行func1函数前num1=", num1)
fun1()
print("运行func1函数后num1=", num1)
# 得到:
# 运行func1函数前num1=6
# 函数内修改后num1=2
# 运行func1函数后num1=6
全局变量
num1=6
,在函数func1
内部修改变量num1
的值,调用完函数func1
后第7行代码输出num
的值,发现在函数外部num
的值并没有发生改变。这是因为函数内部、的num1
是一个局部变量,对局部变量的任何修改不会影响同名的全局变量
想要在函数内部修改全局变量的值,可以用关键字global
进行声明。希望在函数中使用全局变量,而不是创建局部变量,需要用global
关键字声明。函数中先声明global s
再s=1
这样全局变量s变成了1
num1 = 6 # 全局变量
def fun1():
global num1 # 用global声明变量num1
num1 = 2
print("func1函数内修改后num1=", num1)
print("运行func1函数前num1=", num1)
fun1()
print("运行func1函数后num1=", num1)
# 得到:
# 运行func1函数前num1= 6
# func1函数内修改后num1= 2
# 运行func1函数后num1= 2
func1
中使用global
声明num1
,那么在该函数内部访问的num1
就是全局变量num1
,所以对它的修改也就是对全局变量的修改