python基础笔记9—函数


函数本质上就是一段可执行的代码,可以重复使用。

函数的创建

在这里插入图片描述

def 函数名(参数列表):
    函数体
    return (返回值)#可写可不写
  1. 函数名需要符合标识符的命名规则
  2. 参数可以为空
  3. 不带表达式的return相当于返回None。

参数传递

  • 形参的位置在函数的定义处(a,b)
  • 实参的位置是函数的调用处(2,3)
def  f(x,y):
    z=x+2*y
    return z
#函数调用
result=f(2,3)     #8   
print(result)
res=f(y=2,x=3)    #7   =左边的变量名称称为关键字参数
#res=f(x=3,2)   错误,缺少关键字y
print(res)

函数调用的参数传递

函数调用:

函数名(实际参数)

函数调用的2种方式:

  • 位置传参
    —根据形参对应的位置进行实参传递
    如上面的例子就是位置实参,将2传给形参对应位置上的a,3传给b
  • 关键字传参
    —根据形参名称进行实参传递(关键字不可缺少)
  • 序列传参(list,tuple,str类型)
    —序列类型作为参数列表传递。要求序列元素个数=参数个数
def f(a,b,c):
    print("a=",a,end=',')
    print("b=", b,end=',')
    print("b=", c)
lst=[6,7,8]#列表
f(*lst)#相当于f(lst[0],lst[1],lst[2])
t=(10,20,30)#元组
f(*t)
s='abc'#字符串
f(*s)

运行结果:

a= 6,b= 7,c= 8
a= 10,b= 20,c= 30
a= a,b= b,c= c
  • 字典关键字传参
    —实参和形参通过字典进行传递和匹配,字典的key为形参,value为实参(key的名字要和形参对应)
def f(a,b,c):
    print("a=",a,end=',')
    print("b=", b,end=',')
    print("b=", c)
#d={'c':2,'a':1,'z':6}   字典关键字z在函数中没有叫z的形参
d={'c':2,'a':1,'b':6}
f(**d)

运行结果

a=1,b=6,c=2

在函数调用过程中,进行参数的传递。
若实参是不可变对象,在函数体的修改不影响实参的值(arg1的修改不影响n1的值)
若实参是可变对象,在函数体内的修改会影响实参的值(列表为可变对象,故arg2的修改会改变n2的值)

def fun(arg1,arg2):
    print('arg1=',arg1)
    print('arg2=',arg2)
    arg1=100#将arg1重新赋值为100
    arg2.append(10)#对arg2追加10
    print('arg1=',arg1)
    print('arg2=', arg2)
    return
n1=11      #不可变对象
n2=[1,2,3] #可变对象
print('n1=',n1)
print('n2=',n2)
print('--------------------------')
fun(n1,n2)#n1,n2为形参arg1,arg2对应的实参,实参和形参名称可以不一致。位置传参
print('n1=',n1)
print('n2=',n2)

运行结果:

n1= 11
n2= [1, 2, 3]
--------------------------
arg1= 11
arg2= [1, 2, 3]
arg1= 100
arg2= [1, 2, 3, 10]
n1= 11
n2= [1, 2, 3, 10]

函数的返回值

  • 若函数无返回值(函数执行完毕后,不需要给调用处提供数据,return可省略)
  • 函数的返回值,如果是1个,直接返回原类型
  • 函数的返回值,如果是多个,返回的类型为元组

函数的参数定义

默认值参数

函数定义式,对默认值参数(在定义形参时,给形参赋了值),则只有实参的值与默认值不符时,才需要传递(将实参的值赋给形参,形参的默认值被实参覆盖)
注意: 默认值参数需依次从右至左存在,即默认值参数的右侧应全为默认值参数

#def fun(a,b=10,c):    错误
def fun(a,b=10):#b有默认值10,称b为默认值参数
    print(a,b)

#函数的调用
fun(100)     #100,10
fun(100,30)  #100,30   b的默认值被实参30覆盖了

不定长参数

  • 个数可变的位置参数
  1. 定义函数时,可能无法事先确定传递的位置实参的个数,此时可使用可变的位置参数
  2. 用*定义个数可变的位置参数
  3. 返回结果为一个元组
  • 个数可变的关键字参数
  1. 定义函数时,可能无法事先确定传递的关键字实参的个数,此时可使用可变的关键字参数
  2. 用**定义个数可变的关键字参数
  3. 返回结果为一个字典(键值对形式出现)
    **注意:**函数定义时,个数可变的位置/关键字参数只能定义1个。函数定义时,既有个数可变的关键字形参又有个数可变的关键字形参,位置形参放在前面
def fun(*f):
    print(f)

fun(1)                 #(1,)
fun(20,30,40)          #(20, 30, 40)
fun([1,2,3])           #([1, 2, 3],)

def fun1(**f):
    print(f)

fun1(a=1)              #{'a': 1}
fun1(a=10,b=20,c=100)  #{'a': 10, 'b': 20, 'c': 100}

def fun(*x,**y):      #位置形参放在关键字形参之前
    pass              #没想好怎么写,先占位

!!!!
将序列中的元素都转为位置实参:函数调用时使用*
将字典中的元素都转为关键字实参:函数调用时使用 **

def fun(a,b,c):#形参
    print('a=',a)
    print('b=',b)
    print('c=',c)

fun(10,20,30)#位置传参    a= 10,b= 20,c= 30
lst=[11,12,13]    
fun(*lst)#函数调用时,将列表中的每个元素转换为位置实参传入。  a= 11,b= 12,c= 13
fun(a=20,b=30,c=40)#关键字传参  a= 20,b= 30,c= 40
dic={'a':111,'b':122,'c':133}
fun(**dic)##函数调用时,将字典中的每个键值对转换为关键字实参传入。  a= 111,b= 122,c= 133

特定位置后的形参只能用关键字传参

'''需求:实参c,d只能采用关键字实参传递'''
def fun(a,b,*,c,d):#*号之后的形参只能采用关键字传参
    print('a=',a)
    print('b=',b)
    print('c=',c)
    print('d=',d)
    
fun(1,2,c=3,d=4)

函数定义时的顺序问题
几种参数定义方式混合使用时,遵循下面的顺序:
位置形参>*元组形参(个数可变的位置传参)>关键字传参>**字典形参(个数可变的关键字形参)>默认值参数
下面几种定义方式是合法的

def fun1(a,b,*,c,d,**args):
    pass
def fun2(*args1,**args2):
    pass
def fun3(a,b=10,*args):
    pass
def fun4(a,*args,b,c):#b,c在*后面,所以调用时应该用关键字传参
    pass

变量的作用域

变量的作用域指的是程序代码能访问该变量的区域。

分类

  1. 局部变量
  • 在函数内定义并使用的变量
  • 只在函数内部有效
  • 若局部变量使用global声明,则变为全局变量。(global只能在函数内声明,否则无效)
  1. 全局变量
  • 函数体外定义的变量
  • 可作用于函数内外
def fun1(a,b):
    c=a+b#c为局部变量,因为c是在函数体内定义的变量。a,b为形参,作用范围也为函数内部,相当于局部变量
    print(c)
#print(c) 报错,因为超出了起作用的范围。
name='anna'#name为全局变量
print(name)
def fun2():
    print(name)
fun2()
def fun3():
    global age   #age为函数内部定义的变量,为局部变量。用global声明,故变为全局变量
    age=10
    print('age=',age)
# 调用函数
fun3()#age=10
print('age=',age)#age=10
def fun3(a,b):
    global c
    c=a+b
    print('c=',c)
# 调用函数
fun3(1,2)#c=3
print('c=',c)#c=3

递归函数

定义

在函数的函数体内部调用了函数本身

递归的组成部分

  • 递归调用条件
  • 递归终止条件

调用过程

  • 每调用一次函数,都在栈内分配一个栈帧
  • 每执行完一次调用后都释放相应空间

优缺点

  • 占内存,效率低
  • 思路/代码简单

例:用代码计算6!=720

def fac(n):
    if n!=1:
        res=n*fac(n-1)
        return(res)
    else:
        return 1
print(fac(6))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值