Python15_函数

初识函数

认识函数:在一个完整的项目中,某些功能会反复的使用,那么会将功能封装成函数,当我们要使用的时候直接调用函数即可

本质:对功能的封装

优点:

  1. 简化代码结构,增加了代码的复用度

  2. 如果想要修改某些功能或者debug,只需要修改对应的函数即可

定义函数

#格式:
def 函数名(参数列表):
    语句
    return 表达式

函数名:遵循标识符规则

参数列表(参数1,参数2,参数3……,参数n):调用者给函数的信息,任何传入参数(变量)必须放在小括号中,以逗号分隔

():参数列表的开始和结束

语句:函数封装的功能

return:结束函数,并返回信息给函数的调用者

表达式:要返回给调用的信息

注意:最后的return 表达式 可以不写

def myPrint():
    print("sunck is a good man!")

无参无返回值函数

def myPrint():
    print("sunck is a good man!")

函数的调用

格式:函数名(参数列表)

函数调用的本质:实参给形参赋值的过程

含参函数

需求,编写一个函数,给函数一个字符串和一个年龄,在函数内部打印出来

def myPrint(str, age):
   print(str,age)
   

实参(实际参数):调用函数时给函数传递的数据,本质是值

形参(形式参数):定义函数时小括号中的变量,本质是变量

传参的过程实际上是实参给形参赋值的过程

参数必须按顺序传递,个数目前来看要对应

含返回值函数

需求:给函数两个数,返回这两个数的和

def add(num1, num2):
   return num1 + num2
   
res = add(1,3)
print(res)

传递参数

  • 分类
    1. 值传递:传递的是不可变类型,如tuple,string,number
    2. 引用传递:传递的可变类型,如list,set,dict
#值传递
def func1(num):
   num = 10   
temp = 20
func1(temp)
print(temp)

#引用传递
def func2(myList):
   myList[0] = 100
   
list1 = [1,2,3,4,5]
func2(list1)
print(list1)

注意:对于大多数开发语言来说,基本数据类型的变量都存在栈区,对象类型的都存在堆区,常量存在常量区,代码存在代码段

对于常量,存储在常量区,变量存储的是数据的地址,如果两个变量的值相同,则指向常量区的同一个数据,故如果用id()打印两个变量的地址,结果相同

a = 10
b = 10
print(id(a),id(b))  #输出结果相同

关键字参数

允许函数调用的时参数的顺序与定义时不一样,python解释器能够用参数名字匹配匹配参数

  • 是否显示指定参数,要一方便自己阅读为目的
def myPrint(str,age):
    print(str,age)

myPrint(age=18,str="sunck is a good man")

默认参数

概念:调用函数时,如果没有传递参数,则使用默认参数

**如果要用默认参数,最好将默认参数放到最后

def myPrint(str="sunck is a good man", age = 18)
    print(str,age)
    
myPrint()

def myPrint2(str, age = 18):
    print(str,age)
    
myPrint2("sunck is a good man")

不定长参数

def:能处理比定义时更多的参数

形式一

def func(name, *arr):   #arr可以为任意符合规范的标识符
    print(name)
    for x in arr:
        print(x)

*加了星号(*)的变量存放所有的未命名的变量参数,如果在函数调用时没有指定参数,它就是一个空元组

def mySum(*arr):
    sum = 0
    for x in arr:
        sum += x
    return sum

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

形式二

必须以关键字形式传递参数

**代表键值对的参数字典,和*所代表的意义类似

def func2(**kwargs):    #kwargs为字典
    print(kwargs)
    print(type(kwargs))
func2(x=1,y=2)

小结

def f(*t):
	print(t)
f(*(1,2,3,4))	# *在此处相当于拆包,在形式参数位置相当于打包,**类似

def ff(**kw):
	print(kw)
ff(**{"name":"aodongbiao","age":23})

可以接受任意参数

def func3(*args, **kwargs):
    pass

匿名函数

概念:不使用def这样的语句定义函数,使用lambda来创建匿名函数,返回值就是表达的结果

  • 特点:
  1. lambda只是一个表达式,函数体比def简单
  2. lambda的主体是一个表达式,而不是代码块,仅仅只能在lambda表达式中封装简单的逻辑
    3.lambda函数有自己的命名空间,且不能访问自由参数列表之外的或全局命名空间里的参数
  3. 虽然lambda是一个表达式,而且看起来只能写一行,但是与C和C++里面的内联函数不同

格式:lambda 参数1,参数2……,参数n:epxreesion

#求两个数的和
sum = lambda num1,num2:num1+num2

print(sum(1,2))


stus=[{"name":"zhangsan","age":23,"sex":"male"},
      {"name":"lisi","age":12,"sex":"femaile"}
]
print("排序前:",stus)
# 根据年龄排序
res=sorted(stus,key=lambda  x:x["age"])
#x:将stus中的元素挨个传给lambda函数,将其中单个元素的整体传给x,x["age"]即字典中的age的值。再把age的值作为参数用于比较
print("排序后:",res)

#动态输入函数
#coding=utf-8
def test(a,b,func):
	return func(a,b)
func = input("please input a function:")	#这是python2中的写法,如果是python3中,func = evla(input("please input a function:"))	#eval即可将输入的语句转为python2中的形式
#假设输入了:lambda x,y:x+y
print(11,22,func)
#则test函数可以计算两个数的和

翻外篇

  • 之import

格式:from modename import name1, name2

  • “_”

如果for循环里面的临时变量在循环体里面并没有用到,则可以用"_",告诉读者该临时变量在循环体里面并没有被使用

for _ in range(10):
    pass

  • 之函数补充

函数也可以看做一种数据类型

def sum(a,b):
	return a+b
f = sum
print(f(1,2))
  • 之作用域与闭包
  1. python中,变量的作用域时以函数为单位的
  2. global修饰变量时,说明使用的是最外层的全局变量
  3. nonlocal 修饰时,说明使用的是嵌套层的变量,即非局部变量
  4. 如果不使用nonlocal或者global关键字,则内部函数不能可以访问但是不能修改外部的量,使用了关键字则可以进行更改

闭包
在一个函数里面又定义了一个函数,且这个函数用到了外面的变量。那么里边的这个函数及用到的外面的变量统称为闭包。闭包的本质是函数的嵌套,外层函数返回内层函数的地址。

def test(number):
	def test_in():
		print(number+100)
	return test_in
ret = test(100)	#返回test_in,并将test_in里面的number用100替换
ret()	#输出200
#ps:也可以给test在定义时添加形参,则在ret调用时必须进行传参。
  • 闭包的应用及详解
def test(a,b):
	def test_in(x):
		print(a*x + b)
	return test_in

line1 = test(1,1)	#令line1指向test_in的空间,此时test_in里面用的a是1,b是1
line1(0)
line2 = test(10,4)	#如果发现没有指向test_in的引用,则直接将原来空间里面的a、b进行修改。但是此时有引用指向test_in,就重新开辟一块空间,将原来的test拷贝进去,但是将a赋值为10,b赋值为4,然后将这里面的test_in返回给line2
line2(0)

之递归
def:函数自己调用自己
编写递归或循环时,一般先考虑出口(结束条件)问题

之高阶函数

def:函数的参数或函数的返回值是函数的函数

def handle(func, *param):
    return func(*param)

def my_sum(*param):
    sum = 0
    for i in param:
        sum += i
    return  sum

print(handle(my_sum,1,2,3,4,5))

之函数的本质

对于函数,实际上在一块空间内存储了函数体,而函数名(不加括号)指向该空间。
因此可以将函数名看做一个普通的变量,进行赋值等操作。而在其他语言(如C、C++中),就必须通过函数指针进行。

猜你喜欢

转载自blog.csdn.net/qq_34873298/article/details/89600209