python - 函数

本文详细介绍了Python中的函数概念,包括函数的创建、返回值、参数类型(位置参数、关键字参数、默认值参数、收集参数)以及调用方式(普通调用、作为参数传递、嵌套函数、闭包、工厂函数、修饰函数和lambda函数)。通过示例展示了如何定义和使用这些函数特性,强调了参数的顺序和使用关键字的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

函数的概念

什么是函数呢?可以说是一堆代码的集合,更确切的是能解决一个问题的代码集合,那为什么需要函数 呢?在写代码,码程序的时候,时常遇到一些重复性多的又有些许变动的要求,就需要函数了。比如在欢迎屏上打印来屏的名字,加上一成不变的祝福语句,那就再适合不过了。如:

guest = ['王老五','obama','李四','张三']
str1 = '\n欢迎茬临...'
str2 = '\n祝您事事顺心,万事如意!'
for guester in guest:
    print(guester,str1,str2)

    
王老五 
欢迎茬临... 
祝您事事顺心,万事如意!
obama 
欢迎茬临... 
祝您事事顺心,万事如意!
李四 
欢迎茬临... 
祝您事事顺心,万事如意!
张三 
欢迎茬临... 
祝您事事顺心,万事如意!

如果每次我们都要敲一遍,是有点复杂,我们把上面的需求做成函数来调用,下次只需要客户明单即可。

def greeting():		#定义函数
    for guester in guest:
        print(guester)
        print(str1,str2)

        
greeting()		#调用函数
王老五

欢迎茬临... 
祝您事事顺心,万事如意!
obama

欢迎茬临... 
祝您事事顺心,万事如意!
李四

欢迎茬临... 
祝您事事顺心,万事如意!
张三

欢迎茬临... 
祝您事事顺心,万事如意!

函数的创建

函数体:

def funtionName(参数1,参数2,...,):
	<函数体>
	<return>

定义函数

函数 的定义使用def ,后面跟funtionName,也即是函数名字(首字母小写),函数名字尽量使用英文,不得使用下列:

  • 数字开头
  • 名称中有特殊符号
  • 和python内置函数重名
    取名时尽量做到见名知义,采用驼峰命名法。
def printMax():

def account_append():

函数的说明

在函数给人使用时,简短的函数名字不足以让别人了解其中的奥秘,为此,可以在python中,添加长字符串说明函数的功能与使用方法。

def printMax():
	```
		提供一个迭代对象,遍历后输出最大值


	```

函数的返回值

函数在没有使用return 返回数据时,默认返回值是None.

type(lookType)
<class 'NoneType'>

函数的参数

位置参数

在函数定义或调用时,默认使用的是位置参数。如:

#定义一个函数,默认有a,b二个参数,a是需要比较大小的列表,b是布尔值,为真时比大,为假时比小。
lista = [1,2,3,4,5,5,5,6,9,0]
def printMax(a,b):
		```
		这是一个比较大小的函数,需要提供二个参数,a为列表,b为布尔值,为真
		比较大,为假时比较小。
		```
    if b:
        print(max(a))
    else:
        print(min(a))
        
printMax(lista,True)			#比大
9
printMax(lista,False)		#比小
0

在调用时,需要密切留意参数的位置,位置错误会引发函数崩溃。

Traceback (most recent call last):
  File "<pyshell#136>", line 1, in <module>
    printMax(True,lista)
  File "<pyshell#133>", line 3, in printMax
    print(max(a))
TypeError: 'bool' object is not iterable

如果我们定义一个函数,参数过多时,可以在函数调用时采用关键字参数。

关键字参数

为解决上述调用函数需对位置函数密切留意的问题,python支持在函数调用时采用关键字参数。

printMax(b = False,a = lista)
0
printMax(b = True,a = lista)
9

这样,就可以不必太过留意参数之间位置的问题,但是在调用时,位置参数必须在最左则,不然会调用失败。

printMax(b = False,lista)
SyntaxError: positional argument follows keyword argument

大家想一下,如果我这样写会怎么样:

printMax(b = True,(19,22,33,44,55,66,1))
printMax([19,22,33,44,55,66,1],b = True)

默认值参数

在函数定义时,我们对有一项是可有可无的需求时,可以使用参数的默认值。在未录入时采用默认值,有录入时采用录入值。

def printPersonInfo(name,age,phone=''):
    print(name,age,phone)

    
printPersonInfo('h',18)
h 18 
printPersonInfo('h',18,13718271890)
h 18

收集参数

  • args
    在我们不知道需要多少个参数时,如需要太多参数,定义太费手时,可以使用
    args,底层args是用tuple。
def printMax1(*args):
    print(*args)
    return max(*args)
printMax1(1,2,3,4,5,1,9,0)
1 2 3 4 5 1 9 0
9
  • **args
    底层是用字典保存参数,
def printPerson(index,**args):
    print('args的信息是%s' % args)
    for each in args.items():	#打印字典的k,v值,以tuple方式保存。
        print(each)
printPerson(1,a=2,c=3,csdn='www.csdn.ort')
args的信息是{'a': 2, 'c': 3, 'csdn': 'www.csdn.ort'}
('a', 2)
('c', 3)
('csdn', 'www.csdn.ort')

混合参数

记住一个原则,位置参数必须最左,字典收集参数必须最右
位置参数->默认参数->元组收集参数->字典收集参数。

def boring(name,sex='man',*aspect,**info):
    str1 = ''
    str2 = ''
    for i in aspect:
        str1 += i
    for each in info.items():
        str2 += each[0]+'是'+str(each[1])
    print('%s的性别是%s\n,respt是%s\n,info是%s\n'%(name,sex,str1,str2))

    
boring('csdn','women','black','cool','sweet','love',salary=10000,cars='bmw')
csdn的性别是women
,respt是blackcoolsweetlove
,info是salary是10000cars是bmw

这里的sex在收集参数之前,所以必须使用关键字指定,否则会被 收集哦

参数小知识

TIPS:
在一些函数定义里面,我们可以看到:

  • 必须使用关键字参数
funA(100,200)
100 200
funA(100,b=200)
100 200
Traceback (most recent call last):
  File "<pyshell#4>", line 1, in <module>
    funA(b=200,a=100)
TypeError: funA() got some positional-only arguments passed as keyword arguments: 'a'

‘/’之前的参数必须使用位置参数,调用时不得使用关键字参数

  • 必须使用关键字参数
    与上相反的是,必须要指定关键字参数也有其定义方式:
def funB(a,*,b,c):
    print(a,b,c)

    
funB(100,200,300)
Traceback (most recent call last):
  File "<pyshell#9>", line 1, in <module>
    funB(100,200,300)
TypeError: funB() takes 1 positional argument but 3 were given
funB(100,b=200,300)
SyntaxError: positional argument follows keyword argument
funB(100,200,c=300)
Traceback (most recent call last):
  File "<pyshell#11>", line 1, in <module>
    funB(100,200,c=300)
TypeError: funB() takes 1 positional argument but 2 positional arguments (and 1 keyword-only argument) were given
funB(100,b=200,c=300)
100 200 300
funB(a=1,b=200,c=300)
1 200 300

函数的调用方式

普通调用方式

在定义好一个函数后,可以在控制台,直接输入函数名进行调用。也可以把函数名赋值给一个变量,如:

def funAdd(a,b):			#定义一个函数,把里面的二个参数进行相加
    return a+b			#返回两个参数相加的结果

funAdd(3,5)		#普通调用方式
8
a = funAdd		#把funAdd赋值给a变量,深层次是把funAdd的id给了a,如果funAdd后面跟了小括号,则是把funAdd的返回值赋值给了变量a。
id(funAdd)		#查看函数的id
2658843228720
id(a)			#查看变量a的id.
2658843228720
a is funAdd			#变量a和函数funadd是否是同一对象。
True

a(3,4)			#正常调用。
7

将函数作为参数调用

将函数作为参数传送

def time_master(func):			#time_master函数的参数是func哦。。
    start = time.time()
    print('time开始计时了哦~~')
    func()					#运行程序的调用
    end = time.time()
    print('time计时结束了哦~~')
    print('func使用了%d 秒'%(end-start))		#输出相关信息。

    
time_master(funC)			#调用master,将funC函数做为参数进行传递,这里的funC可不能带()哦,不然就变成返回值了。
time开始计时了哦~~
func运行ok
time计时结束了哦~~
func使用了2

tips:想一想,为啥func()不能有相应的参数呢,如果有参怎么定义函数呢?
这里等下会讲到,涉及到闭包,工厂函数呢…

函数嵌套函数

说到嵌套,应该不会陌生,循环有嵌套,函数也有嵌套,这里我浅显的说一些个人的理解,现在的术语应该是套娃,一层套一层,差不多这个意思。

def outer():
    print('这是外层函数')
    def inner():
        print('这是内层函数')
    inner()

    
outer()
这是外层函数
这是内层函数
a = outer
a()
这是外层函数
这是内层函数

闭包函数

闭包就是外部函数中定义一个内部函数,内部函数引用外部函数中的变量,外部函数的返回值是内部函数;

​ 闭包函数和嵌套函数类似有以下基本特征。

  • 首先它是一个嵌套函数,有外层函数,内部函数。
  • 内部函数调用外部函数的变量。
  • 外部函数调用时需要将内部函数返回。
    示例:
    设计一个有记忆功能的列表,每次增加一个元素,就会列出里面所有的元素和。

def outer():			#定义一个外层函数,特征一
    lista = []			#定义一个内部函数需要用到的变量;特征二
    def inner(num):		#定义一个内部函数
        lista.append(num)
        print('列表现有%d个元素,它们的和为:%d'%(len(lista),sum(lista)))
    return inner			#将内层函数作为返回值返回给外层函数;特征三

summary = outer()
summary(4)
列表现有1个元素,它们的和为:4
summary(6)
列表现有2个元素,它们的和为:10
summary(20)
列表现有3个元素,它们的和为:30

工厂函数

这也是闭包的一种,可以在外部函数中定义程序的轮廓,内部函数作为生产出来的模具使用,比如,自定义扩展,m的n次幂。工厂函数有闭包的一切特征。

def base(n):			#定义一个外层函数,n即是内层函数需要用到的变量;
    def exp(m):		#定义一个内层函数
        return m ** n		#返回m的n次幂。
    return exp				#将内层函数作为返回值返回给外部函数;

squer = base(3)				#3次幂
cube = base(2)				#2次幂
squer(2)
8
squer(3)
27
cube(2)
4
cube(3)
9

修饰函数

语法糖中的一种,也是闭包函数的一种。和当函数作参数传递有一点不同。

def cost_time(f):		#定义一个外层函数,将f函数作为参数传入内层函数中去。
    def inner(*args,**kwargs):			#定义一个内层函数,设置参数为可变收集参数,这样可以与外层f函数的调用保持一致。
        print('开始计时..')
        start = time.time()
        f(*args,**kwargs)
        end = time.time()
        print('结束计时...\n耗费时间为:%.4f'%(end - start))
    return inner

mycost = cost_time(funa)
mycost(1,2,3,4,5,6,'Fishc',a=3,b=9,c=33,d='ok')
开始计时..
1
2
3
4
5
6
Fishc
('a', 3)
('b', 9)
('c', 33)
('d', 'ok')
结束计时...
耗费时间为:2.1551

除此方法外,也可使用另一个方式,修饰符的方式,在定义需要修饰的函数上方,采用‘@’加修饰函数。

@cost_time
def syjik(a,b,/,d):
    print(a,b,'必须为位置参数传递进来,d可为关键字参数也可为位置参数传递.',d)

    
syjik('skj','ok',111)
开始计时..
skj ok 必须为位置参数传递进来,d可为关键字参数也可为位置参数传递. 111
结束计时...
耗费时间为:0.0348
syjik('skj','ok',d=111)
开始计时..
skj ok 必须为位置参数传递进来,d可为关键字参数也可为位置参数传递. 111
结束计时...
耗费时间为:0.0284
syjik('skj',b='ok',d=111)
开始计时..
Traceback (most recent call last):
  File "<pyshell#159>", line 1, in <module>
    syjik('skj',b='ok',d=111)
  File "<pyshell#150>", line 5, in inner
    f(*args,**kwargs)
TypeError: syjik() got some positional-only arguments passed as keyword arguments: 'b'

lambda函数

lambda也是一句话函数,在map,filter中大有用处,示例:

map
mapped = map(lambda x: x *2,[1,2,3,4,5,6,7])
mapped.__next__()
2
next(mapped)
4
list(mapped)
[6, 8, 10, 12, 14]
filter
filed = filter(lambda x: x>7,map(lambda x: x *2,[1,2,3,4,5,6,7]))
filed.__next__()
8
next(filed)
10
tuple(filed)
(12, 14)

other
mapped1 = lambda x,y:y**x
mapped1(2,4)
16
mapped2 = lambda x:lambda y :y**x
mapped2(2)(3)
9

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值