@函数的定义
以下是简单的规则:
函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 ()。
任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数。
函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。函数内容以冒号起始,并且缩进。return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。
基本格式:
def 函数名(参数):
函数体
return 返回值
@函数的参数
- 必需参数
必需参数须以正确的顺序传入函数。调用时的数量必须和声明时的一样。
调用 printme() 函数,你必须传入一个参数,不然会出现语法错误: - 关键字参数
关键字参数和函数调用关系紧密,函数调用使用关键字参数来确定传入的参数值。
使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值。
以下实例在函数 printme() 调用时使用参数名:
#可写函数说明
def printme( str ):
"打印任何传入的字符串"
print (str)
return
#调用printme函数
printme( str = "关键字参数")
以下实例中演示了函数参数的使用不需要使用指定顺序:
#可写函数说明
def printinfo( name, age ):
"打印任何传入的字符串"
print ("名字: ", name)
print ("年龄: ", age)
return
#调用printinfo函数
printinfo( age=50, name="runoob" )
- 默认参数
调用函数时,如果没有传递参数,则会使用默认参数。以下实例中如果没有传入 age 参数,则使用默认值:
def printinfo( name, age = 35 ):
"打印任何传入的字符串"
print ("名字: ", name)
print ("年龄: ", age)
return
#调用printinfo函数
printinfo( age=50, name="runoob" )
print ("------------------------")
printinfo( name="runoob" )
运行结果:
名字: runoob
年龄: 50
------------------------
名字: runoob
年龄: 35
- 不定长参数
你可能需要一个函数能处理比当初声明时更多的参数。这些参数叫做不定长参数,和上述 2 种参数不同,声明时不会命名。python自定义函数中有两种不定长参数,第一种是*args,在传入额外的参数时可以不用指明参数名,直接传入参数值即可。第二种是**kargs,这种类型返回的是字典,传入时需要指定参数名。
加了一个星号 * 不定长参数会以元组(tuple)的形式导入,存放所有未命名的变量参数。加了两个星号 ** 的参数会以字典的形式导入,存放已命名的变量参数。
实例1:
#使用不定长参数传固定值,注意,b、c可省略,a不可省略
def fuzhi(a, *b, **c):
print(a)
print(b)
print(c)
fuzhi(1,25,3,69,58,48,58)
运行结果:
1
(25, 3, 69, 58, 48, 58)
{
}
实例2:
def fuzhi(a, *b, **c):
print(a)
print(b)
print(c)
fuzhi(1,25,3,69,58,48,58,name='lly',age=18,she='yrr')
运行结果:
1
(25, 3, 69, 58, 48, 58)
{
'name': 'lly', 'age': 18, 'she': 'yrr'}
@匿名函数
python 使用 lambda 来创建匿名函数。
所谓匿名,意即不再使用 def 语句这样标准的形式定义一个函数。
lambda 只是一个表达式,函数体比 def 简单很多。
lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
lambda 函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。
虽然lambda函数看起来只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。
语法:
lambda [arg1 [,arg2,…argn]]:expression
实例1:
# 可写函数说明
sum = lambda arg1, arg2: arg1 + arg2
# 调用sum函数
print ("相加后的值为 : ", sum( 10, 20 ))
print ("相加后的值为 : ", sum( 20, 20 ))
运行:
相加后的值为 : 30
相加后的值为 : 40
实例2:
# 匿名函数:简化函数定义
# 格式: lambda 参数1,参数2,。。:运算
s = lambda a, b: a + b
print(s(4, 4))
def func(x, y, func):
print(x, y)
print(func)
s = func(x, y)
print(s)
# 调用func
func(1, 2, lambda x, y: x + y)
list2=[{
'a':13,'b':56},{
'a':40,'b':49},{
'a':50,'b':1}]
m=max(list2,key=lambda x:x['b']+x['a'])
print(m)
运行结果:
8
1 2
<function <lambda> at 0x00000228306BBB70>
3
{
'a': 40, 'b': 49}
实例2:
# map
list1 = [1, 2, 4, 7, 8, 9, 6, 3]
result = map(lambda x: x + 2, list1)
print(list(result))
func = lambda x: x if x % 2 == 0 else x + 1
result = func(5)
print(result)
result = map(lambda x: x if x % 2 == 0 else x + 1, list1)
print(list(result))
# reduce(): 对列表中的元素进行加减乘除运算
from functools import reduce
tuple1 = (3, 4, 5, 6, 7, 8)
result = reduce(lambda x, y: x + y, tuple1)
print(result)
tuple2 = (4,)
result = reduce(lambda x, y: x + y, tuple2, 10)
print(result)
# 动手测试减法
list2 = [12, 3, 5, 56, 4, 23, 14, 19, 10, 9]
result = filter(lambda x: x > 10, list2)
print(list(result))
运行结果:
[3, 4, 6, 9, 10, 11, 8, 5]
6
[2, 2, 4, 8, 8, 10, 6, 4]
33
14
[12, 56, 23, 14, 19]
@闭包
闭包是函数式编程的一个重要的语法结构,函数式编程是一种编程范式 (而面向过程编程和面向对象编程也都是编程范式)。在面向过程编程中,我们见到过函数(function);在面向对象编程中,我们见过对象(object)。函数和对象的根本目的是以某种逻辑方式组织代码,并提高代码的可重复使用性(reusability)。闭包也是一种组织代码的结构,它同样提高了代码的可重复使用性。
不同编程语言实现闭包的方式是不同的,python中闭包从表现形式上看,如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure)。
例如:
def func(a, b):
c = 10
def inner_func():
s = a + b + c
print('相加后的结果是', s)
return inner_func
# 调用func
ifunc = func(6, 9)
ifunc1 = func(2, 8)
print(ifunc)
print(ifunc1)
ifunc()
ifunc1()
运行结果:
<function func.<locals>.inner_func at 0x000001A7FE08B840>
<function func.<locals>.inner_func at 0x000001A7FE08BBF8>
相加后的结果是 25
相加后的结果是 20
@装饰器
装饰器实际上就是为了给某程序增添功能,但该程序已经上线或已经被使用,那么就不能大批量的修改源代码,这样是不科学的也是不现实的,因为就产生了装饰器。
实例1:
import time
def decorate(func):
print('------------第一层--------------')
def wrapper(*args, **kwargs):
print('正在校验中---------------')
time.sleep(2)
print('校验完毕------------------')
func(*args, **kwargs)
print('###########下一步就是return了###############')
return wrapper
@decorate
def f1(n):
print('---------------f1----------------', n)
@decorate
def f2(name, age):
print('---------------f2----------------', name, age)
运行结果:
------------第一层--------------
###########下一步就是return了###############
------------第一层--------------
###########下一步就是return了###############
实例2:
import time
def decorate(func):
print('------------第一层--------------')
def wrapper(*args, **kwargs):
print('正在校验中---------------')
time.sleep(2)
print('校验完毕------------------')
func(*args, **kwargs)
print('###########下一步就是return了###############')
return wrapper
@decorate
def f1(n):
print('---------------f1----------------', n)
@decorate
def f2(name, age):
print('---------------f2----------------', name, age)
f1(4)
print(f1)
f2('lly', 18)
print(f2)
@decorate
def f3(student, clazz='1905'):
print('{}的学生如下: '.format(clazz))
for stu in student:
print(stu)
students = ['lly', 'llg', 'ffrf', 'yrr']
f3(students)
print(f3)
运行结果:
------------第一层--------------
###########下一步就是return了###############
------------第一层--------------
###########下一步就是return了###############
正在校验中---------------
校验完毕------------------
---------------f1---------------- 4
<function decorate.<locals>.wrapper at 0x000001C8F77ABAE8>
正在校验中---------------
校验完毕------------------
---------------f2---------------- lly 18
<function decorate.<locals>.wrapper at 0x000001C8F77ABD08>
------------第一层--------------
###########下一步就是return了###############
正在校验中---------------
校验完毕------------------
1905的学生如下:
lly
llg
ffrf
yrr
<function decorate.<locals>.wrapper at 0x000001C8F77ABE18>
注意:当有两个装饰器时,函数优先加载最近的装饰器。