python函数

普通函数

基本定义及调用

语法:def 函数名(参数列表):

                        函数体

#无参
def hello():
    print("hello world")

hello()

#有参
def sum(a,b):
    return a+b

print(sum(2,9))
函数标注

形参得到标注方式是在形参后面加冒号和数据类型,函数返回值的标注方法是在形参列表的def语句结尾的冒号之间加上复合符号"->"和数据类型,但注意,函数标注仅仅是标注了参数和返回值的类型,不会限定参数和返回值的类型,在函数定义和调用时,参数和返回值的类型是可以改变的

def fun(a:str,b:str="is my favourite")->str:
    s=a+" "+b
    print("函数标注",fun.__annotations__)
    print("传递的参数:",a,b)
    return s
print(fun('python'))

#函数标注 {'a': <class 'str'>, 'b': <class 'str'>, 'return': 
#<class 'str'>}
#传递的参数: python is my favourite
#python is my favourite

return语句

return[表达式]语句用于退出函数,选择性的向调用方返回一个表达式,不带表达式的return返回None

变量作用域

变量起作用的代码范围成为变量作用域。

在函数内部使用global来定义全局变量x,其同名全局变量在函数外已经定义,该变量在函数内外是同一个变量,所以在函数内部该变量所有的运算结果也反映到函数外

x,y=2,200   #全局变量
def fun():
    global x
    x,y=1,100   #局部变量的作用域仅在函数内部
    print("函数内部: x=%d,y=%d"%(x,y))
print("函数外部: x=%d,y=%d"%(x,y))#调用函数前
fun()
print("函数外部: x=%d,y=%d"%(x,y))#调用函数后

#函数外部: x=2,y=200
#函数内部: x=1,y=100
#函数外部: x=1,y=200

在以上代码中发现,全局变量y和局部变量y是两个不同的变量,局部变量y在函数fun()调用过程中不会改变全局变量y的值,说明局部变量与全局变量名字相同,局部变量会在函数内部屏蔽同名的全局变量。

如果函数内部用global定义的全局变量在函数外部没有同名的,则调用该函数后,创建新的全局变量。

def fun1():
    global c
    c=90
    print(c)
fun1()
print(c)

#90
#90
 函数的递归调用
  1. 子问题需与原问题相同的问题,规模小且更简单
  2. 调用本身有边界条件

用递归的方式实现非负整数的阶乘

def fun(n):
    if n==0:
        return 1
    else:
        return n*fun(n-1)
print(fun(5))

#120

使用递归方式求斐波那契数列的第n个元素

def fun(n):
    fn=0
    if n==1:
        fn=0
    elif n==2:
        fn=1
    else:
        fn=fun(n-1)+fun(n-2)
    return fn
print(fun(3))

#1

匿名函数

匿名函数是没有采取使用def语句定义函数的标准方式,而用lambda方式俩简略定义的函数。匿名函数没有函数名,表达式只包含一个表达式,有以下特点:

1.表达式简洁

2.lambda表达式的主体只是一个表达式,而不是一个代码块,只能封装有限的逻辑。

3.匿名函数有自己的命名空间,不能访问自己参数列表之外或全局命名空间里的参数。

定义如下:

匿名函数名=lambda[arg1,[arg2......argn]]:expression

用匿名函数求两个数的平方差:

fun=lambda x,y:x**2-y**2

print(fun(7,6))

求1-20内偶数和的总和 

fun=lambda a,b:sum(i for i in range(a,b+1)if i%2==0)
print('the sum of even numbers between {} and {} is {}'.format(1,20,fun(1,20)))

#the sum of even numbers between 1 and 20 is 110

参数传递

字符串,数字,元组是不可变对象,列表,字典是可变对象。

给参数传递不可变对象

def fun (a):
    print("函数内部赋值前,变量值:",a,"变量地址:",id(a))
    a+=10
    print("函数内部赋值后,变量值:",a,"变量地址:",id(a))
    return a
a=10
print('函数外部调用前,变量值:',a,"变量地址:",id(a))
fun(a)
print('函数外部调用后,变量值:',a,"变量地址:",id(a))

函数外部调用前,变量值: 10 变量地址: 140719143406296
函数内部赋值前,变量值: 10 变量地址: 140719143406296
函数内部赋值后,变量值: 20 变量地址: 140719143406616
函数外部调用后,变量值: 10 变量地址: 140719143406296

给参数传递可变对象

def fun (a):
    print("函数内部赋值前,变量值:",a,"变量地址:",id(a))
    a+=[5,6,7]
    print("函数内部赋值后,变量值:",a,"变量地址:",id(a))
    return a
a=[1,2,3,4]
print('函数外部调用前,变量值:',a,"变量地址:",id(a))
fun(a)
print('函数外部调用后,变量值:',a,"变量地址:",id(a))


函数外部调用前,变量值: [1, 2, 3, 4] 变量地址: 1424846803328
函数内部赋值前,变量值: [1, 2, 3, 4] 变量地址: 1424846803328
函数内部赋值后,变量值: [1, 2, 3, 4, 5, 6, 7] 变量地址: 1424846803328
函数外部调用后,变量值: [1, 2, 3, 4, 5, 6, 7] 变量地址: 1424846803328

总结:

1.不可变对象:调用函数传递不可变类型的值给a,传递的只是a的值,没有影响a本身,若在函数内部修改a的值,则生成一个新的a。

2.可变对象:调用函数传递可变类型的值给a,则是将a真正传递过去,在函数内部修改a后,函数外部的a也会收到影响。 

参数类型

位置参数

顺序与数量与声明时保持一致。

关键字参数

在函数调用时,参数的传入使用了参数的名称,此类参数成为关键字参数。

注意:关键字参数必须在位置参数的后面

def fun(a,b,c):
    print(a,b,c)
    return
fun(1,c=2,b=3)

#1 3 2

 当三个参数都是关键字参数时,顺序任意。

默认参数

在函数定义时,某个参数使用了默认值,则该函数是默认参数。

不定长参数

如果希望函数的参数不确定,则使用不定长参数,定义方式有两种:

1.  *parameter

2.  **parameter

前者接收多个实参并将其放入一个元组中,后者则接收键值对并将其放入字典中

def fun(*a):
    sum=0
    for i in a:
        sum+=i
    return sum

print(fun(1,2,3,4,5,6))

#21
def fun(**a):
    print(a)
    for k,v in a.items():
        print(k,":",v)


fun(name='zhangsan',id='00001',age='19')


{'name': 'zhangsan', 'id': '00001', 'age': '19'}
name : zhangsan
id : 00001
age : 19

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值