发现函数要学的东西太多,决定分章节记录。
定义函数
一个函数应该先做出定义:
def text():
print('xxxx')
text()
这是一个最简单的函数及其定义方式,以def xxx(): 开头。运行函数直接写出函数名。
函数传参
函数名中定义的参数称为形式参数,即形参。
指定传参
函数名中定义的参数称为形式参数,即形参。
传参可用指定位置传参或关键字传参,也可以将两者结合。
def text(x,y):
z = x + y
print(z)
text(5, 6) # 11,指定位置传参
text('hello','world') # helloworld,指定位置传参
text(y=2,x=1) # 3,关键字传参
text(1,y=2) # 3,混合传参,需要注意的是指定位置传参必须放在关键字传参前面
指定位置传参必须按照形参给定位置进行参数设置。
关键字传参不用按照形参给定位置设置参数,但必须根据指定参数名进行参数设置。
同时形参个数有多少,最后传参时必须设置多少位参数。
缺省参数
指函数在定义形参时给定默认值,如果传参时不重新设置参数,则会按照默认值进行传参。
def text(x=3,y=1):
print(f'x = {x}')
print(f'y = {y}')
text(y = 2) # x = 3 y = 2
这里有个比较有意思的事情,算是新手容易踩坑的地方,老手就当个笑话吧。
def text(x,y=1):
print(f'x = {x}')
print(f'y = {y}')
text(2) # x = 2 y = 1
text(2,2) # x = 2 y = 2
text(y=2) # 报错
text(x=2) # x = 2 y = 1
x,y = 1,2 # 常规赋值
print(x,y) # 1 2
当我们在非函数名之类的位置进行赋值的时候,可以用x,y=1,2的形式进行表示,但在设置形参的时候,它是默认逗号做分隔,一个参数后面必须跟一个值。这也就导致了传参的时候会出现一个坑,使用位置传参的时候,它是默认x,y顺序传参,但使用关键字传参,我们无法忽略未设置默认值的参数x而去设置已设置默认值的参数y。
不定长参数
通指含有*xxx,**xxx的形参,有两种其中任何一种都算。其中星号可理解为解压缩的意思。单星号表示存储除字典(dict)以外的参数,双星号可存储字典类型的参数。在理论上,可无限传参。
def show(a, b, *args, **kwargs):
print(f'a={a}')
print(f'b={b}')
print(f'args={args}')
print(f'kwargs={kwargs}')
show(1,2,3,4,5,6,name='张三',age=18) # a=1 b=2 args=(3, 4, 5, 6) kwargs={'name': '张三', 'age': 18}
函数的返回值
函数执行之后使用变量接收或者进一步处理,给调用者的结果为返回值。
def add(a,b):
c = a + b
return c
res = add(1,4)
print(res) # 5
这里和上面的代码块不太一样,单纯的add(a,b)我们是看不到结果的,但函数的确返回了一个结果给我们,这个结果就是供我们进一步处理的,比如我们将add(1,4)返回的结果赋值给res,然后将其打印出来,打印就是进一步处理。
这里有一个地方需要注意,每个函数只能返回一个返回值。
函数的嵌套调用
将一个函数给另一个函数调用,即为函数的嵌套调用。
def fun1():
print('111')
def fun2():
print('222')
fun1()
print('333')
fun2() # 222 111 333
def add(a,b,c):
return a+b+c
def pj(a,b,c):
he = add(a,b,c)
return he / 3
res = pj(1,3,5)
print(res)
def res(*a):
sum1 = 0
for i in a:
sum1 += i
return sum1
def reg(*a):
re = res(*a) / len(a) #星号和a是可以拆开的,一个是代表压缩,一个代表参数
return re
i = reg(1, 2, 3, 5, 3)
print(i)
这三个例子都是关于嵌套调用的实例,讲的都是同一件事情,将另一个函数借用到自己这边,进行自己这边函数功能的处理。
全局变量和局部变量
局部变量:函数内部定义的变量,不同的函数可定义相同变量名,两者互不影响,仅为临时处理函数。
全局变量:指对于当前文件来说,任何位置都可以使用。定义在函数外部,对全局生效。
a = 100 # 全局变量
def text(b):
b = 100 # 局部变量
注意事项
- 两者重复时,局部变量不会影响到全局变量,函数使用局部变量。
a = 100
def text():
a = 200
print(a)
text() # 200,此处为局部变量返回的结果
print(a) # 100,此处为全局变量返回的结果
- 全局变量能在函数内部访问,也可以在外部访问。
a = 100
def text():
print(a)
text() # 100,内部无定义变量,向外寻找,全局变量访问函数内部
print(a) # 100,全局变量访问函数外部
- 函数内部不能直接修改不可变类型全局变量。
a = 100 # 整型Int为不可变类型
def text():
print(a) #原因在于无定义,找不到变量a,无法对此时身份是全局变量的a做出改变
a += 100
print(a)
text()
print(a)
# 报错UnboundLocalError: local variable 'a' referenced before assignment
- 如果一定要在函数内部修改全局变量,可加上global说明
a = 100
def text():
global a # global语句被用来声明x是全局的
print(a)
a += 100
print(a)
text()
print(a)
上面三点可以用一句辅助说明: python在当前位置读取到某个变量时,会向外寻找该变量的定义。一直找到全局,找不到就报错。