1-1-1 def bar(): print('in the bar') def foo(): print('in the foo') bar() foo() 1-1-2 如果把 bar 放在 foo 后面 def foo(): print('in the foo') bar() def bar(): print('in the bar') foo() ---> in the foo in the bar 也能运行 1-1-3 如果换一个位置调用 def foo(): print('in the foo') bar() foo() def bar(): print('in the bar') 这样结果会报错的 ---> in the foo Traceback (most recent call last): File "d:/VSCode/Untitled-2.py", line 5, in <module> foo() File "d:/VSCode/Untitled-2.py", line 3, in foo bar() NameError: name 'bar' is not defined 这是为什么?? 变量的定义:大楼里有小房间,大楼里找一个房间,将 1 放入;x就是门牌号 函数即变量 def test(): pass 相当于,将 pass 代表的函数体,赋值给名字叫 test 的变量。 变量直接调用,test需要通过 test()的方式调用。 所以,函数在内存中是怎样存放的? 在大楼中找一个小房子,把函数体放进房子,函数体就是 一堆字符串,将函数体房间的门牌号,叫做 test python 的回收机制是解释器,解释器是如何回收变量的? python解释器中,有一个概念叫 引用计数 引用计数:x=1 现在内存中,把 x=1 这个值,实时存放;如果 y=x,实际上是把房间的门牌号又加上了一个 y 引用计数,x代表一次引用,y代表一次引用;一共是 2 次引用。 那么 python 什么时候 会 回收 1 呢?在 y 这个门牌号没了,x 这个门牌号 也没了的情况,就会清掉。也就是 没有门牌号了,就将 1 清掉。 因为没人用了,就要 将房间里的东西,清出去,这就是 python 的回收机制。 匿名函数 有的函数是没有名字的,可以不定义名字——这就是匿名函数。 calc = lambda x:x*3 print(calc(3)) ---> 9 其实这就 相当于 一个函数了,除了变量之外,没有名字;后面为了调用,起了一个变量名 calc 这个和定义的函数没有区别,只是没有名字而已。 函数就是变量,匿名函数没有 def 没有声明函数名;那么它到底是如何存储的呢? lambda 定义的就是函数体,没有门牌号,就意味着,它会被回收。 刚刚赋值了变量,calc;相当于给予了一个门牌号 calc 总结: 函数就是变量,定义一个函数就是相当于把函数体赋值给了函数名。 变量有内存回收机制,函数也是一样的 如果 x=1,所以永远不会被删除,del 就会被删除 del 其实没有删掉内存地址的 1 ,只是把 x 的门牌号摘掉了,这个 1 定期刷新,发现没人引用了,才把它清掉 现在回顾刚刚的 4 段代码: 第 1 段代码: def foo(): print('in the foo') bar() foo() 会出错,因为调用 foo 时,运行到 bar()时,bar未定义 会找一个房间放函数体,把 print('in the foo') bar() 放入 然后给一个 门牌号 foo;函数体,在内存中就是一堆字符串,可以定义。 但是在运行的时候,第一步 print 可以打印执行 但是 bar();需要寻找带有 bar 门牌号的房间,但是没有,所以报错了 第 2 段代码: 在 foo 之上定义了函数 bar def bar(): print('in the bar') def foo(): print('in the foo') bar() foo() bar 在上面能够正常运行。 第 3 段代码: 将 bar 放到下面了,和上面是否有区别? def foo(): print('in the foo') bar() def bar(): print('in the bar') foo() 为什么没有区别? 如果有一个 x=1 变量;找一个屋子,将 1 放入;x就是门牌号 又来一个 y=2 内存中会将 2 存入 写入代码的方式 x=1 y=2 调用时,print(x,y)就ok 如果 换一种方式, y=2 x=1 print(x,y) 运行结果一样的 变量在使用的时候,实际上是分为两步的: 第 1 步,是定义 第 2 步,是调用 python 是一种解释运行的语言,因为在调用之前,已经是被python 解释器,解释到的 只要解释到,内存中就存在,存在就是可以用的。 为什么第二段 和 第三段 代码 没有区别? 第三段,先定义 foo; foo会把函数体当做一堆字符串放入内存当中,此刻 foo 是存在的 然后继续定义 bar;将bar 的函数体 放入内存当中。 此刻 bar 也是存在的了 第三部调用,也是可以的 先声明,后调用,只要调用之前存在了,就能调用到。 第 4 段代码: def foo(): print('in the foo') bar() foo() def bar(): print('in the bar') 为什么会报错?解释执行,解释器会先把 foo 指向 代码块,然后直接就执行了 此刻,执行时,会发现,bar房间号,并没有对应到一个房间。是在下面才存在的,此刻并不存在。 所以报错了,函数就是一种 “变量”。