python整理 2021-10-14

本文详细介绍了Python函数的参数传递方式,包括位置参数、关键字参数、默认参数和可变参数,并通过示例进行解析。此外,讲解了闭包的概念和构成条件,以及其在代码中的表现。最后,探讨了装饰器的原理和应用场景,展示如何利用装饰器增强函数功能而不改变原有代码。
摘要由CSDN通过智能技术生成

函数的参数传递

位置的参数传递

就是我们通常使用的方式,一对一对应

例子

def fun_01(x, y, z):
    return x, y, z
print(fun_01(1,2,3))

输出:

(1, 2, 3)

不多讲

关键字参数传递

把参数的名称与值绑定在一起

实例

def connect(num1,num2):
    return num1/num2
print(connect(num1 = 1,num2 = 2))
print(connect(num2 = 1,num1 = 2))

输出

0.5
2.0

参数默认值

也是很好理解,就是参数设置一个默认值,这跟我们定义变量没赋值时,默认为0(int类型)是类似的。

def sum(a,b,c=20):
    return a + b + c
print(sum(10,10))
print(sum(10,10,10))

输出

40
30

可变参数(难点、重点)

可变参数就是传入函数的参数是可变的,

语法格式如下:

def functionname([formal_args,] *args, **kwargs):
    "函数_文档字符串"
    function_suite
    return [expression]
  • 以星号(*)开始的变量args会存放所有未命名的变量参数,args为元祖
  • 以**开始的变量kwargs会存放命名参数,即形如key=value的参数,kwargs为字典

例子

# *args的使用
def test1(*args):
    print(args)
# **kwargs的使用
def test2(**kwargs):
    print(kwargs)
# 两者的混用
def test3(*args,**kwargs):
    print(args)
    print(kwargs)
print("*args的使用")
test1(1,2,3,'a','b','c')
print("**kwargs的使用")
test2(a = 1, b = 2,c = 3, d = 4)
print("两者的混用")
test3(1,2,3,a = 4,b = 5)

输出

*args的使用
(1, 2, 3, 'a', 'b', 'c')
**kwargs的使用
{'a': 1, 'b': 2, 'c': 3, 'd': 4}
两者的混用
(1, 2, 3)
{'a': 4, 'b': 5}

从以上我们可以看出

  • 使用*可以将未命名的参数打包成元组类型
  • 使用**可以将命名的参数打包成字典类型

闭包

函数的引用

先来看一段代码

def fun():
    print("hello world")
fun()
fun

输出

hello world
<function __main__.fun()>

从这里我们可以看出,使用fun()和fun的结果完全不一样,原因是fun()表示调用fun()这个函数,会执行其中的代码,而fun表示一个变量,它引用的是一个函数块,引用一个函数(我认为就是一种指向),当然也可以多个函数指向同一个函数块

如:

def fun():
    print("hello world")
fun()
fun_new = fun
fun_new()

输出

hello world
hello world

我们可以看出输出结果是一样的。

什么是闭包

先举个例子

def test(one):
    def test_in(two):
        print(one + two)
    return test_in
test(100)

满足闭包的三个条件

  • 嵌套在函数里面
  • test_in中的变量是外部函数test的参数one
  • 外部函数test返回值是内部函数test_in的引用

我们输出下结果

<function __main__.test.<locals>.test_in(two)>

我们会发现它输出的是一个引用值,这是因为我们只调用了test()函数,但实际上并没有调用test_in函数,所以返回的就是一个引用值

def test(one):
    def test_in(two):
        print(one + two)
    return test_in
test_new = test(100)
test_new(100)

当我们这样写的时候,就成功调用test_in函数

至于作用,我百度搜下也还不是很清楚,按我的想法就是可以重复使用

def test(one):
    def test_in(two):
        print(one + two)
    return test_in
test_new = test(10)
#这样可以隐藏内部调用,调用者可以不关心内部如何调用的
test_new(100)
test_new(200)

装饰器

装饰器本质就是一个Python函数,它可以在不改动其他函数的前提下,对函数的功能进行扩充。通常情况下,装饰器用于以下场景:

  • 引入日志
  • 函数执行时间统计
  • 执行函数前预备处理
  • 执行函数后清理功能
  • 权限校验
  • 缓存

先举个简单的例子

def fun_one():
    print("fun_one")

现在有这个一个需求就是在函数中输出一句话,表示函数正在执行,这时候可以这么实现

def fun_one():
    print("fun_one")
    print("fun_one is running")

如果只有一个函数需要表示正在执行的话,我们这样写无疑是简便的,但如果还有其他函数也要表示函数正在运行呢,如果有10000个函数,那岂不是要多出大量重复代码,这样是不合算的,所以为了减少代码重复,我们可以创建一个新的函数专门记录函数,如下:

def print_logo():
    print("函数正在运行")
def fun_one():
    print("fun_one")
    print_logo()

上述代码虽然可以实现功能,但破坏了原有代码的逻辑结构。如果要求已经实现的函数,不能修改,只能扩展,即遵守“封闭开放”原则,那就不允许修改的,在源代码基础上进行扩展,能够更好的维护,如果对源代码直接进行更改的话,会导致后期越来越难以维护,最终有可能演变成“屎山”。

类似这样
在这里插入图片描述
截图来源于:http://www.javashuo.com/article/p-yuqcxibh-x.html

而装饰器可以满足上述要求,在Python中,装饰器的语法屎以@开头,下面屎简单的装饰器使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值