Python学习之路05 函数深度解析与高级特性探讨-下

前言
在编程的学习过程中,函数是一个重要的里程碑。它不仅可以帮助我们组织和简化代码,还可以提高代码的可读性和重用性。在本章的学习中,我们将深入探讨Python中函数的使用,从基本的函数定义和调用开始,逐步了解参数的使用、返回值的设定以及变量的作用域。此外,我们还将探讨高级主题,如lambda表达式和nonlocal语句的使用。
.
通过理解和掌握这些概念,您将能够更有效地编写Python代码,并将您的编程技能提升到一个新的水平。我们将通过简明扼要的解释和实用的例子来展示每一个主题的实际应用,为您提供一个实实在在的学习经验。

个人主页:尘觉主页

个人简介:大家好,我是尘觉,希望我的文章可以帮助到大家,您的满意是我的动力

在csdn获奖荣誉: csdn城市之星2名
⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ Java全栈群星计划top前5
⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣  端午大礼包获得者
⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ 阿里云专家博主
⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ 亚马逊DyamoDB结营

欢迎大家:这里是CSDN,我总结知识的地方,欢迎来到我的博客,感谢大家的观看
如果文章有什么需要改进的地方还请大佬不吝赐教 先在次感谢啦

文章目录

  • Python 05 之函数【参数,返回值,嵌套调用,作用域,匿名函数】
    • 9、LEGB规则
    • 10,闭包
    • 11,装饰器
      • 11.1,多个装饰器能否用在同一个函数上呢?
      • 11.2,如何给装饰器传递参数呢?
    • 12,生成器
      • 12.1生成器表达式
    • 13,递归
      • 13.1经典应用汉诺塔
    • 14,函数文档、类型注释、内省
      • 14.1 函数文档
      • 14.2 类型注释
      • 14.3 内省
    • 15,高阶函数
    • 总结

Python 05 之函数【参数,返回值,嵌套调用,作用域,匿名函数】

9、LEGB规则

作用域的影响范围不同,这些作用域冲突的时候,python会先选择谁,其实是 有 先后顺序的,这就是 LEGB规则 这也是 python的解析机制, L代表 local局部作用域, E代表 Enclosed是嵌套函数的外层函数的作用域,而 G是 Global全局作用域, B代表 Build-In叫做内置作用域,前三个我们介绍过了,

当局部作用域与全局作用域冲突时,会优先选择局部作用域的值 ,除非你用global语句,

那这里内置作用域是最没地位的,比如是 BIF你只有随便起一个跟内置函数一样的变量名就足以把它给毁了 。

str="大家好"
str(53)
print(str)

image-20230903220023183

10,闭包

我们之前讲的嵌套函数是闭包和装饰器的基础。

Python学习之路05 函数深度解析与高级特性探讨-下_第1张图片

def funA():
    x = 880

    def funB():
        print(x)

    return funB


print(funA())
funA()()
funny = funA()
funny()

image-20230903221109961

​ 左侧的代码还是说明,想调用嵌套函数内部的funB,必须通过调用 funA来实现,注意这里funA里定义 x的值, funB是将 x打印出来。 那有没有办法可以不通过调用 funA来 调用 funB?

没错就是使用函数的返回值,这里直接将 funB作为 funA的返回值返回,注意, 函数只有在定义和调用的时候才会用到小括号

这是发现 funA是一串代码,**这串代码就是 funB函数的引用接着这段代码先是通过调用 funA来调用 funB,**这里使用的是两个括号 (也就是说 funA()返回的funB 而不是 funB()funB(),所以 再加个括号才会实现 funB的调用),因为 funB不用输入实参,所以这里后面加两个括号和一个括号效果是一样的。接着可以把 funA直接赋值给一个变量,这样直接使用这个变量名就可以了。用这个变量名就可以了。

虽然局部变量不能使用,但却能够通过间接的方式给访问到。LEGB的 E就是拥有这么神奇的特性,也就是说 对于嵌套函数来说,外层函数的作用域是会通过某种形式给保存下来,尽管这个函数已经调用完了,但外层作用域里面的变量是会被保存下来的 。

所谓闭包,也被称为工厂函数:

def power(exp):
    def exp_of(base):
        return base ** exp

    return exp_of


square = power(2)
cube = power(3)
print("2 square", square(2))
print("3 square", square(3))
print("4 cube", cube(4))
print("5 cube", cube(5))

Python学习之路05 函数深度解析与高级特性探讨-下_第2张图片

上面这段代码说明,嵌套函数的外层作用域会被保存下来,这里square=power(2)就是外层作
用域 exp为 2的这个值,这里理解一下 python的思路。

def outer():
    x = 0
    y = 0

    def inner(x1, y1):
        nonlocal x, y
        x += x1
        y += y1
        print(f"现在x={x},y={y}")

    return inner


move = outer()
move(1, 2)
move(-2, 2)

​ 这段代码使用nonlocal语句, 它有使 内层函数修改到外层函数作用域的特性,就可以实现建立带记忆功能的函数。 也就是说, move在这里就等同于 inner。

11,装饰器

复习闭包的两个核心技巧:

  1. 利用嵌套函数的外层作用域具有记忆能力这个特性,让数据保存在外层函数的参数或变量中

  2. 将内层函数作为返回值给返回给返回,这样就可以从外部间接的调用到内层的函数。

闭包其实讲的是把函数做回一个返回值给返回更厉害的是函数还可以作为一个参数传递给另一个参数

 def myfun():
    print("正在调用myfun")


def report(func):
    print("开始调用")
    func()
    print("结束")

report(myfun)

Python学习之路05 函数深度解析与高级特性探讨-下_第3张图片

​ 上面这段代码的意思是,先创建一个myfunc()的函数,注意的是在设置第二个函数 report()时,一定要给它一个形参,因为这个形参要在函数里引用其 它 函数时用到,上面的那段代码就使用的是 func 作为形参,引用时别忘记加小括号哦,

因为我们引用的是函数而不是变量名。那在引用myfunc()函数时,直接将 myfunc函数的名字作为实参传入到 report()函数里就可以了。这两个函数都实现的是打印。 这里注意函数作为参数的使函数名,引用的时候注意要加括号才能 实现函数的引用。

利用这中效果,我们就可以设置一个统计传入函数运行时间的函数:

import time
def time_master(func):
    print("开始")
    start=time.time();
    func()
    end=time.time()
    result=end-start
    print("一共耗时",result)

def myfunc():
    time.sleep(1)
    print(1111)

time_master(myfunc)

Python学习之路05 函数深度解析与高级特性探讨-下_第4张图片

​ 上面代码的意思是:先导入了一个time模块,后面就可以使用该模块里的函数。 time模块的time()函数可以获取当前的时间戳, time模块里的 sleep()函数让运行停留一段时间,先睡一段时间。定义的 time_master(func)函数的作用是在引用函数之前,把时间戳给到 start这个变量名,

然后引用函数,引用完后再 把时间戳给到 stop这个变量名,那这两个时间戳的差值就是result 相当于引用 func()函数运行所花费的时间。

myfunc()函数的作用是:是先暂停1秒钟然后打印 1111。然后用 time_master()这个函数统计 myfunc()函数运行的时间。

​ 但这并不是最优的解决方案,因为每次想要测试函数运行的时间都需要显示的去调用这个time_master()函数, 最好 的方案就是可以让 它 自觉地去执行这个统计时间的函数,那就需要引入装饰器了

import time


def time_master(func):
    def call_func():
        print("开始")
        start = time.time();
        func()
        end = time.time()
        stop = end - start
        print("一共耗时", stop)
    return call_func


@time_master
def myfunc():
    time.sleep(1)
    print(1111)


myfunc()

Python学习之路05 函数深度解析与高级特性探讨-下_第5张图片

​ 从结果上来看和上面最初的那段代码的结果是一样的,那这段代码中发生了什么呢?首先可以看到我们并没有 显式 的调用 time_master()函数,

只需要在需要统计时间的函数前加上@time_master就可以了

它实现的原理是: 闭包 +函数参数,这里 @加上装饰器的名字(这里就是我们定义的统计时间的函数),其实是个语法糖 ,这个装饰器原来的样子是下面这个样子

import time


def time_master(func):
    def call_func():
        print("开始")
        start = time.time();
        func()
        end = time.time()
        stop = end - start
        print("一共耗时", stop)
    return call_func



def myfunc():
    time.sleep(1)
    print(1111)


myfunc=time_master(myfunc)
myfunc()

Python学习之路05 函数深度解析与高级特性探讨-下_第6张图片

可以看到它实现的逻辑是: 先设定一个闭包,这个外部函数是 time _master(),它的返回值是它的内部函数 call_func(),它可以实现函数运行时间的统计,time_master(myfunc)的意思是,把myfunc()函数作为参数传递给 time_master 函数,然后返回 call_func 函数,把这个返回的call_func()函数赋值给 myfunc (这里大概解释一下为什么非得定义一个 call func()这样一个内部函数,那是因为这个内部函数要作为一个返回值赋值给 myfuc,所以要使用闭包),这样 myfunc() 就输出了同样的结果了

这里有个疑问把 time_master(myfunc)赋值给 myfunc 了,那这个时候 myfunc 是个变量还是函数?

我尝试着来解释一下,这个 time_master(myfunc)其实相当于是 call_func 函数,把它赋值给了myfunc,那这个时候 myfunc 其实相当于是 call func 函数,

​ 所以最后要写成 myfunc()才能输出结果,注意这里的 myfunc 和 time_master(myfunc)里的 myfunc 不是同一个东西,time_master()里的是我们上面定义的 myfunc()函数,在这里作为实参传入到 time_master(),并把它赋值给新的myfunc,其实这里用其它字符串的变量名也可以实现同样的效果:(下一页的代码)

​ 之前我们有提到过语法糖,我们讲 f字符串是 format 的一个语法糖,那现在这个装饰器的语法糖就是: myfunc-time_master(myfunc),我们把它去掉,在函数定义的前面,换成@加装饰的名字,这个就是装饰器的语法糖。使用了它也就是说我们调用myfunc()的时候我们并不是直接调用 myfunc,而是把它作为一个参数塞到上面的装饰器里,然后去调用这个装饰器。

有了装饰器就可以在需要代码时,不用修改原函数,直接给函数套上一层金钟罩铁布衫就可以了(这句话还不太理解,还不太理解装饰器的牛逼)。

import time


def time_master(func):
    def call_func():
        print("开始")
        start = time.time();
        func()
        end = time.time()
        stop = end - start
        print("一共耗时", stop)
    return call_func



def myfunc():
    time.sleep(1)
    print(1111)


abc=time_master(myfunc)
abc()

image-20230903225359527

11.1,多个装饰器能否用在同一个函数上呢?

答案是可以的,直接看例子:

def add(func):
    def inner():
        x=func()
        return x+1
    return inner


def cube(func):
    def inner():
        x=func()
        return x*x*x
    return inner


def square(func):
    def inner():
        x=func()
        return x*x
    return inner


@add
@cube
@square
def text():
    return 2

print(text())

image-20230903225917448

这段代码的结果是65,从结果上判断它的调用顺序是先调用 square,然后是 cube,最后是 add。顺一下这个逻辑:在定义的函数est()上面用了上面几个装饰器的语法糖,会使得 test()函数的变量名 test作为参数依照语法糖的顺序传入到对应的装饰中,如果对应的装饰其中有函数的引用
(注意函数的引用是需要加括号的) 那这个 test()函数就会引用。这里得到的最终结果是因为装饰器里 return的是一个数。

11.2,如何给装饰器传递参数呢?

这个相对比较难,属于进阶的语法。

import time


def logger(msg):
    def time_master(func):
        def call_func():
            print("开始")
            start = time.time();
            func()
            end = time.time()
            stop = end - start
            print("一共耗时", stop)

        return call_func

    return time_master


@logger(msg="A")
def funA():
    time.sleep(1)
    print("AAAAA")


@logger(msg="B")
def funB():
    time.sleep(1)
    print("BBB")


funA()
funB()

Python学习之路05 函数深度解析与高级特性探讨-下_第7张图片

这个代码明显可以看到装饰器是带有参数的,可以发现这这个参数的实现是通过多加了一层嵌套实现的。看不懂,没关系我们先把这个语法糖给拆掉,把它写成它传统的样子:

import time


def logger(msg):
    def time_master(func):
        def call_func():
            print("开始")
            start = time.time();
            func()
            end = time.time()
            stop = end - start
            print("一共耗时", stop)

        return call_func

    return time_master


def funA():
    time.sleep(1)
    print("AAAAA")


def funB():
    time.sleep(1)
    print("BBB")


funA=logger(msg="A")(funA)
funB=logger(msg="B")(funB)
funA()
funB()

Python学习之路05 函数深度解析与高级特性探讨-下_第8张图片

​ 以funA为例:首先 logger()这个装饰器 最外层需要传递一个参数 msg,我们令这个 msg为 A后面有引用到这个参数,到目前为止我们引用到的是time_master()这个函数,也就是这三个函数的中间的那一层,

​ 但我们要的是 call_func的引用,所以我们就需要在调用一次,调用 time_mastr就是引用的 call_func(),就是在后面继续加括号,里面传入 (funA),

也就是函数的名字。这样就可以通过嵌套的方式来实现参数的传递,第一次调用把参数扔进去,第二次调用把函数扔进去。

最后在funA()调用的就是call_func

12,生成器

​ 有没有什么办法让函数再退出之后还能保留状态呢?闭包和全局变量都可以实现。 但过多的使用全局变量会污染命名空间,闭包又相对复杂 。 引入生成器,就是使用 yield表达式来代替return语句


def counter():
    i = 0
    while i <= 5:
        yield i
        i += 1

print(counter())

image-20230904092042168

我们定义上面这个函数,去调用这个函数时,发现得到的不是一个返回值,而是一个生成器对象。如何使用它呢?直接把它放到 for语句中:

def counter():
    i = 0
    while i <= 5:
        yield i
        i += 1

print(counter())

for i in counter():
    print(i)

Python学习之路05 函数深度解析与高级特性探讨-下_第9张图片

​ 这里counter()生成器的作用就是每次调用的时候提供一个 数据也就是每次执行到 yield i的时候就生成一个数据,暂停并保留状态,下一次调用时从 i+1开始调用 。你可以把生成器 比作 一个制作机器, 它的作用就是每调用就提供一个数据,并保留当前的状态 。 生成器可以看作是一种特殊的迭代器, 它 首先不走回头路,还支持 next()函数

def counter():
    i = 0
    while i <= 5:
        yield i
        i += 1

c=counter()
print(next(c))
print(next(c))
print(next(c))
print(next(c))
print(next(c))
print(next(c))
print(next(c))

Python学习之路05 函数深度解析与高级特性探讨-下_第10张图片

​ 把counter()赋值给 c,发现 c是一个生成器,搭配 next()函数,因为 它 不能回头,且保留当前状态, 当里面满足条件的值输出完后,继续输出就会报错。

def counter():
    i = 0
    while i <= 5:
        yield i
        i += 1

c=counter()

print(c[2])

Python学习之路05 函数深度解析与高级特性探讨-下_第11张图片

生成器不能被索引,它 不是列表, 它每次生成一个数据 。

12.1生成器表达式

我们之前讲元组的时候,就预告过这一节的到来,列表有推导式,元组就没有,如果非要将列表推导式的那对方括号变成圆括号,就会出现:

t = (i ** 2 for i in range(10))
print(next(t))
print(next(t))
print(next(t))
print("==========")
for i in t:
    print(i)

Python学习之路05 函数深度解析与高级特性探讨-下_第12张图片

这种利用推导式的形式获得生成器的方法,叫做生成式表达式。列表推导式 是 一下把所有的数值生成出来放在一个列表里面,生成器则像一个母鸡,一次只下一个蛋。

13,递归

它的概念属于算法的范畴,天才程序员用递归。 递归就是函数调用自身的过程 。 函数之间不仅可以相互调用,也可以调用自己本身

注意Ctrl+C强制将下面的程序停下来,要不然 它 就会没完没了。

def funA():
    print(123)


def funB():
    print(2222)
    funA()


def funC():
    print(33333333)
    funC()

funB()

funC()

Python学习之路05 函数深度解析与高级特性探讨-下_第13张图片

利用这种无限循环,给它改一下:

def funC(i):
    if i > 0:
        print(33333333)
        i -= 1
        funC(i)


funC(3)

Python学习之路05 函数深度解析与高级特性探讨-下_第14张图片

​ 加上一个条件语句,让递归在恰当的时候进行回归,那么失控的局面就得到了控制**。也就是说要让递归停止必须得有一个结束条件,且每次都要向这个结束条件去靠近,这个才是精髓** 。我们 对比一下迭代和递归看一下 它们的效率如何 :先求一下一个数的阶乘

Python学习之路05 函数深度解析与高级特性探讨-下_第15张图片

​ 毋庸置疑都得到了相同的结果。 从语法上看 n从 10开始,最后当 n=1是输出的是 1。但是注意这里并没有 n=n-1这样一个循环,是不是因为 return的作用, return语句是在定义函数的时候用的,满足条件就返回一个结果,

​ 我来试着解释一下:按理来说,这个函数的 n总会递归到 n=1的时候,这个时候应该返回 1。我们来看这个循环,当 factRecur(n-1)里面的 n为 2时, n-1=1,此时n-1=1作为实参传进 factRecur(n)里,这时新一轮的 n=1,条件语句 n==1判断成立, 应该返回 1啊!!? 而不应该去执行 else啊。确实,这样想并没有错,当 n等于 1的时候 factRecur(n)的返回值确实应该是 1,这里发生了什么

​ 也就是说我们要计算的是factRecur(5),当 n等于 5时, factRecur(5)的返回值是 5 * factRecur(4),但此时 factRecur(4)是个函数没有具体的数值,这个时候就继续调用 factRecur(4),它输出的值为 4*factRecur(3),这样下去一直进行到 factRecur(1)返回 1之后,在 往 上套娃:

  1. factRecur(5)=5* factRecur(4)
  2. factRecur(4)= 4*factRecur(3)
  3. factRecur(3)=3*factRecur(2)
  4. factRecur(2)=2* factRecur(1)
  5. factRecur(1)=1

​ 理解了吗?就是说要想计算 factRecur(5)得需要知道 factRecur(4),而要想知道 factRecur(4)得知道 factRecur(3)这样一层一层下去,一直循环到 factRecur(1)才能把 factRecur(5)得值给求解出来。这样得逻辑对比下,递归得效率似乎就更麻烦一些,一层套一层,但 也不明显,看下面这个

例子:斐波那契数列,这个数列的大概意思就是下一个数,是前两个数之和,前两个数是 1和 2.

Python学习之路05 函数深度解析与高级特性探讨-下_第16张图片

当输入12是效率体现的还不明显:

Python学习之路05 函数深度解析与高级特性探讨-下_第17张图片

​ 当n值为 120时, fibRecur()算了好久,这里使用了强制暂停,而使用迭代时几乎是瞬间得出结果。递归需要算很久就是因为递归逻辑上的效率问题,每一次调用递归函数, 它 并不会立即返回,而是要等到最底层的那个函数返回,然后再一层一层的往上走。

13.1经典应用汉诺塔

这个游戏是这样的,目标就是要把这三块金片移动到C柱子上,每次只能移动一块,且小金片必须在大金片的上方。

Python学习之路05 函数深度解析与高级特性探讨-下_第18张图片

Python学习之路05 函数深度解析与高级特性探讨-下_第19张图片

14,函数文档、类型注释、内省

函数是一个结构组件在函数的外部是不需要关心函数内部的执行细节的,更需要关注的是函数的接口和执行后的结果。

14.1 函数文档

​ 开发手册和函数文档可以帮助你不去理解某个定义函数内部的执行逻辑,帮你快速理解该函数的作用。在 python中使用 **help()**函数可以快速查看一个函数的使用文档。

help(print)

Python学习之路05 函数深度解析与高级特性探讨-下_第20张图片

​ 我们来看一下这个help()函数会展示一些什么样的内容: 函数的原型、函数的功能介绍和各个参数的类型及作用 。函数文档就是函数的说明书,创建函数文档也很简单:

def exchange(dollar,rate=7.27):
    """
    功能: 美元-> 人民币
    :param dollar:美元
    :param rate:汇率 7.27(2023-9-4)
    :return: 人民币数量
    """
    return dollar*rate

print(exchange(100))

image-20230904103013147

上面这段代码时创建了一个把美元转换为人民币的函数,定义完函数后,先输进去的字符串就是这个函数的函数文档注意,函数文档一定要在函数的最顶部,它不会被打印出来,而是作为函数的文档被保存起来的 。 同样使用 help()来查看一下:

Python学习之路05 函数深度解析与高级特性探讨-下_第21张图片

14.2 类型注释

def times(s: str, n: int) -> str:
    return s * n

print(times("hello",3))

image-20230904103505119

​ 比如上面定义的这个函数,作者希望调用者传入到s参数中的类型是字符串类型, n参数是整数型,且这个函数将返回一个字符串类型的返回值:

我们按照作者的要求,先传入字符串,再传入一个数字,就实现了把这个字符串重复了3遍,这是作者的期望,如果说调用者非要胡来, python也是不会阻止的

​ 因为函数定义中的:str只是类型注释,是给人看的,不是给机器看的 。 当代码逐渐膨胀起来,多起来的时候,这个类型注释就会很有用了,避免 python的混乱 除此 之外,也可以使用默认参数:

Python学习之路05 函数深度解析与高级特性探讨-下_第22张图片

下面的这段代码分别实现了列表、参数类型为整数的列表、和映射的重复,自己看一下下面的代码就好了。

Python学习之路05 函数深度解析与高级特性探讨-下_第23张图片

如果你想要python帮你做一下检测也是可以的,这时候需要用到第三方模块Mypy,它的安装和使用教程不难。

14.3 内省

​ 内省顾名思义就是自己反省,计算机编程领域也有类似的机制,它是指在程序运行的时候能够进行自我检测的一 种机制 。 Python是通过一些特殊的属性来实现自省的,比如说我们想知道一个函数的名字,我们可以在程序运行的时候,过 name来获取,也可以使用 annotations来获取类型注释,使用 doc获取函数文档。注意, 前后要两个下划线

image-20230904110750850

Python学习之路05 函数深度解析与高级特性探讨-下_第24张图片

​ 直接使用doc的话阅读起来不太友好,使用 print()函数可以将转义字符识别出来 。有关python的内省还有很多,在后面讲解类和对象以及方法的时候,会用专门深刻的介绍这里只需要知道有这么回事就可以了。

15,高阶函数

​ 我们前面讲过,函数是可以被当作变量一样传来传去的,当一个函数接收另一个函数作为参数的时候呢,这时候这种函数就被称之为高阶函数 。我们其实已经碰触过这个领域。像是 map、filter、 min、 max、 salty都算是高阶函数,因为 它 们有一个 key参数,可以接受的正是一个参数对象, 高阶函数几乎可以说是函数式编程的灵魂所在,所以 python专程为此搞了个模块叫做functools,它里面包含了非常多的高阶函数和装饰器 ,帮助文档里有,小甲鱼论坛里有翻译版但可能还有很多知识点没学过。

​ 然后我讲解了几个在functools中的一 些函数,有且之前还是内置函数,最后被归类到了functools里面。使用时注意先 import functools,import是导入模块的其中一种方式 。

重点介绍了一下偏函数 ,偏函数是指对指定的函数进行二次包装,通常是将现有的函数部分参数预先给绑定,从而得到一个新函数,拿这个新函数就称之为偏函数。说白了,偏函数的作用就是将一个函数的多个参数给拆分多次进行传递的样子。视频里小甲鱼也没有讲的很清楚,借助文档来讲的,结果就说它是一个装饰器,然后巴拉巴拉,估计 它 的目的就是想让我们了解一下,不用懂得很深,想理解的自己 再看看视频吧。

​ 然后又讲了@wraps,它是一个装饰装饰器的装饰器。这个 functools模块里的好玩的函数还有很多,现在掌握的知识有限,能理解这讲的内容就已经很不错了。这个 functools的文档以后工作中可能会用的到。

总结

经过本章的学习,我们已经对Python中的函数有了深刻的理解。我们学习了如何定义和调用函数,如何利用参数来增加函数的通用性,以及如何通过返回值来传递结果。

除了基本的功能之外,还探讨了更高级的主题,包括、LEGB规则、闭包,装饰器、生成器,递归,函数文档、类型注释、内省,高阶函数,通过理解这些高级特性,我们可以编写更灵活和强大的Python代码。

希望您在学习这一章时找到了它的价值,并且可以利用新学到的知识来提高您的编程技能。记得多加练习和应用所学的知识,因为“学以致用”是最好的学习方法。

感谢您的勤奋和努力学习!祝您编程愉快!

热门专栏推荐
想学习vue的可以看看这个

java基础合集

数据库合集

redis合集

nginx合集

linux合集

手写机制

微服务组件

spring_尘觉

springMVC

mybits

等等等还有许多优秀的合集在主页等着大家的光顾感谢大家的支持

欢迎大家加入我的社区 尘觉社区

文章到这里就结束了,如果有什么疑问的地方请指出,诸佬们一起来评论区一起讨论
希望能和诸佬们一起努力,今后我们一起观看感谢您的阅读
如果帮助到您不妨3连支持一下,创造不易您们的支持是我的动力

你可能感兴趣的:(python,python,学习,开发语言,flask,tornado,scrapy,pyqt)