【Python】函数

函数定义

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")

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值