图片说明
#函数的创建

#函数的创建
def calc(a,b):    #ab称为形参
    c=a+b
    return c
#函数的调用
result=calc(10,20)     #10,20称为实参
print(result)

函数参数传递的内存分析

def fun(arg1,arg2):
    print('arg1',arg1)
    print('arg2',arg2)
    arg1=100
    arg2.append(10)
    print('arg1', arg1)     #arg1 100
    print('arg2', arg2)      #arg2 [22, 33, 44, 10]

n1=11
n2=[22,33,44]
print('n1',n1)
print('n2',n2)
fun(n1,n2)      #形参和实参可以不一致

print('n1',n1)     #n1 11
print('n2',n2)     #n2 [22, 33, 44, 10]

函数调用的参数传递内存分析图:
如果是不可变对象,在函数体的修改下不会影响实参的值 arg1
如果是可变对象,在函数体的修改不会影响实参的值 arg2
图片说明

函数的返还值

如果函数的返回值是多个,返回一个元组
如果没有返回值,return可以不写
函数返回值是一个,直接return

def fun(num):
    odd=[]
    even=[]
    for i in num:
        if i%2:
            odd.append(i)
        else:
            even.append(i)
    return odd,even      

lst=[10,29,34,23,44,53,55]
print(fun(lst))          #([29, 23, 53, 55], [10, 34, 44])

函数定义时,是否需要返回值,视情况而定,写的多了,就清楚了。

函数的参数定义

1.默认值形参
函数定义时,给形参设置默认值,只有默认值不符的时候才需要传递。

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

fun(100)    #100 10
fun(20,30)   #20 30

鼠标放在print()函数上,按住ctrl单机左键就可以打开,里面的内容如下:
def print(self, *args, sep=' ', end='\n', file=None)
可以把end换成\t,相当于修改了print里面的默认值,本来是换行输出的,现在空四格输出

print('hello') 
print('Python') 

print('hello',end='\t') 
print('Python')  

2-1.定义个数可变的位置形参,只能有一个

def fun(*args):   #定义个数可变的位置形参
    print(args)   #结果是元组
    print(args[0])

fun(100)
fun(10,20)
fun(30,40,506,7,0)

2-2.定义个数可变的关键字形参,只能有一个

def fun(**kwargs):
    print(kwargs)

fun(a=10)           #{'a': 10}
fun(a=10,b=30,c=40)   #{'a': 10, 'b': 30, 'c': 40}   结果是字典

在一个函数的定义过程中,即有个数可变的关键字参数,又有个数可变的位置形参,要求位置在前

def fun(*args1,**args2):
    pass

3.关键字形参
*被称为关键字形参

def fun(a,b,*,c,d):      #从*之后,函数调用只能采用关键字参数传递。
    print('a=',a)
    print('b=',b)
    print('c=',c)
    print('d=',d)


fun(a=100,c=300,b=200,d=40)      #关键字实参传递
fun(100,300,c=200,d=40)      #前两个参数,采用位置实参传递,c,d采用关键字实参传递

函数的调用

1.位置实参
2将列表中的每个元素都转换为位置实参传入
3.将字典中的关键值都转为关键字实参传入

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

fun(10,20,30)          #1,调用函数时的参数传递,称为位置传参
lst=[11,22,33]
fun(*lst)                 #2.在调用函数时,将列表中的每一个元素都转换为位置实参传入

fun(a=100,c=300,b=200)      #函数的调用,所以是关键字实参
dic={'a':111,'b':222,'c':333}
fun(**dic)              #3.在调用函数时,将字典中的关键值都转为关键字实参传入

4.关键字实参:

def fun(a,b,*,c,d):      #从*之后,函数调用只能采用关键字参数传递。
    print('a=',a)
    print('b=',b)
    print('c=',c)
    print('d=',d)


fun(a=100,c=300,b=200,d=40)      #关键字实参传递
fun(100,300,c=200,d=40)      #前两个参数,采用位置实参传递,c,d采用关键字实参传递

图片说明

变量的作用域

全局变量:全局变量的作用域为整个程序,
局部变量:而局部变量的作用域为当前函数或循环等
global声明

def fun2():
    global age      #函数内部定义的变量,局部的,但是加上了global声明,就成了全局变量
    age=20
    print(age)

fun2()
print(age)

递归函数

函数调用自己本身,要有终止条件
每递归调用一次函数,都会在栈内分配一个栈针,执行完一行都会释放相应的内存空间
代码简单,但是占用内存空间大,如图所示:
图片说明

def digui(n):
    if n==1:
        return 1
    else:
        return n*digui(n-1)

print(digui(6))