其他分享
首页 > 其他分享> > 20201112 装饰器之函数即变量

20201112 装饰器之函数即变量

作者:互联网


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房间号,并没有对应到一个房间。是在下面才存在的,此刻并不存在。
所以报错了,函数就是一种 “变量”。
 ```

标签:bar,变量,门牌号,20201112,print,foo,装饰,def,函数
来源: https://blog.51cto.com/15149862/2677932