函数定义
def add():
a = 10
b = 20
print(a + b)
add()
结果为30
空函数,使用pass , pass可以作为占位符,也可以用在其他语句
空占位符,就算函数里边不写东西,也不会报错
def nop():
pass
a = input()
if not a:
pass
函数参数
def add(x, y):
print(x + y)
参数检查:校验参数
def add(x, y):
if not isinstance(x, int) or not isinstance(y, int):
print("参数错误")
return
# 功能代码
print(x + y)
add(1 , 2)
如果三个数相加呢?
默认值,必须写在正常参数后面
def add (x, y, z):
print (x + y + z)
add (1, 2, 3)
# 默认参数,从右向左进行
def add (x, y, z = 0):
print (x + y + z)
add (1, 2)
def add (x, y, z = None):
if z:
print (x + y + z)
else :
print (x + y)
add (1, 2, 3)
add (1, 2)
参数定义的顺序忘了呢?
def sub(x, y):
print(x - y)
sub(y=2, x=1)
结果为-1
返回值
def add(x, y):
return x + y
多个返回值,实际返回的是一个元组
面试问:Python中能不能返回两个函数不同的两个值?
答:不能。
下边这样返回的是一个元组,而不是两个值
def add(a, b):
return a, b
print(add(1, 2))
结果为(1,2)
不定长参数(参数组)
元组参数组
参数前加*,传入的参数组成元组。 (可以传不定长的,任意个数)
变量名可以是任意的
def func(*args):
print(args)
func(1,3,5,7)
结果为(1,3,5,7)
字典参数组
参数前加**,传入的参数组成字典,以键等于值的形式传参
(可以传不定长的,任意个数)
def add(**kwargs):
print(kwargs)
add(b=20, a=10)
add(b=20, a=10, c=20)
传两个:可以接受任意类型的参数
def add(*args, **kwargs):
pass
add(10,20,30, b=20, a=10, c=20)
函数作为参数和返回值
函数名也是变量,也可以作为参数和返回值
def func(**kwargs):
print(kwargs)
a = func
a(b=1)
作为参数
def add(a, b, func):
print(func(a) + func(b))
# abs 取绝对值函数
add(-5, 6, abs)
结果为11
作为返回值
def func(a, b):
def add():
return a + b
return add
f = func(2, 5)
print(f())
结果为7
练习题
def func(*args):
ans = 1
if not args:
print(0)
return
for item in args:
if not isinstance(item, (int, float)):
print("参数类型错误")
return
ans *= item
print(ans)
func()
func('a')
func(1,2,3)
函数标注
只会做一个提示作用,并不会限制,就算写反了也没事。了解即可。
# 箭头代表返回值为什么类型的
def func(a:str, b:int = 0) -> str:
print(a)
print(b)
return a
func("hello", 5)
# 内置函数
print(func.__annotations__)
匿名函数 lambda
<u>最多用在参数只调用一次</u>
参数:用逗号分隔
表达式:不能包含循环,return,`elif`,但可以包含else和if
def func(x):
return x * 2
print(func(5))
f = lambda x : x * 2
print(f(5))
f = lambda x,y : x - y if x > y else x + y
print(f(5,6))
# 参数 : 表达式
# lambda [arg1, ] : expression
# 常见用法1:赋值
a = lambda x,y : x+y
# 常见用法2:更改原来函数的定义
import time
time.sleep(1)
time.sleep = lambda x : None
# 常见用法3:
# python2会输出列表
print(map(int(), [1.0,2.0,3.0]))
结果是[1,2,3]
# python3会输出map的一个迭代器
print(map(int(), [1.0,2.0,3.0]))
def square(x):
return x ** 2 # x的2次方
print(map(square, [1,2.0,3.0,4,5]))
# lambda表达式
print(map(lambda x : x**2, [1,2.0,3.0,4,5]))
一个或多个序列
# 这样写不对,不会默认给0
# print(map(lambda x,y : x+y, [1,2,3,4],[5,6,7]))
print(map(lambda x,y : x+y, [1,2,3,4],[5,6,7,8]))
闭包
场景1:求2n+1、3n+5、5n+2、4n+3,有100个地方在用
def func(a, b, n):
return a * n + b
def func1(n):
return 2*n+1
def func2(n):
return 3*n+5
def func3(n):
return 5*n+2
def func4(n):
return 4*n+3
# 在函数里边定义一个函数,返回里边函数的值
def outer(a, b): #1定义
def inner(x): #3定义
return a*x+b #7
return inner #4
f1 = outer(2, 1) #2调用函数 5inner函数
f2 = outer(3, 5)
f3 = outer(5, 2)
f4 = outer(4, 3)
print(f1(5)) #6 8
结果为11
函数中定义函数,内部函数可以引用外部函数中的变量
这是一个优化,想一下加十个接口,一百行代码
def add(a,b):
print(a+b)
def sub(a,b):
print(a-b)
def log(func):
def inner(a,b):
print("函数开始运行")
return func(a,b)
return inner
add = log(add)
add(1,2)
def add(a,b,c):
print(a+b+c)
def sub(a,b):
print(a-b)
def log(func):
def inner(*args, **kwargs): # 支持传任意个参数
print("函数开始运行")
return func(*args, **kwargs)
return inner
add = log(add)
add(1,2,3)
sub = log(sub)
sub(1,2)
这种方法调用时不够简洁,使用@语法(装饰器)
装饰器
def log(func):
def wrapper(*args, **kwargs): # 支持传任意个参数
print("函数开始运行")
return func(*args, **kwargs)
return wrapper
@log # 相当于 add = log(add)
def add(a,b,c):
print(a+b+c)
@log
def sub(a,b):
print(a-b)
add(3,5,7)
sub(3,5)
练习题
def check_params(func):
def wrapper(*args, **kwargs):
rules = func.__annotations__
for k,v in kwargs.items():
if k in rules and not isinstance(v, rules[k]):
print(f"参数 {v} 类型错误,传入类型为:{type(v)},应传入类型为:{rules[k]}")
return # 不写的话,第二个调用的函数就会打印两次
res = func(*args, **kwargs)
# 返回值单独看,所以不能和上一个并列写
if 'return' in rules and not isinstance(res, rules['return']):
print(f"返回值 {res} 类型错误,传入类型为:{type(res)},应传入类型为:{rules['return']}")
return res
return wrapper
@check_params
def func1(name: str, age: int) -> str:
print(name, age)
return name # 这里返回的是啥,打印的返回值就是啥
func1(name="jack",age=5)
print() # 打印换行
func1(name=23,age=5)
print()
func1("jack",5)
print()
func1(23,"a")