zoukankan      html  css  js  c++  java
  • 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房间号,并没有对应到一个房间。是在下面才存在的,此刻并不存在。
    所以报错了,函数就是一种 “变量”。
  • 相关阅读:
    atitit.nfc 身份证 银行卡 芯片卡 解决方案 attilax总结
    atitit.php 流行框架 前三甲为:Laravel、Phalcon、Symfony2 attilax 总结
    Atitit.执行cmd 命令行 php
    Atitit. 图像处理jpg图片的压缩 清理垃圾图片 java版本
    atitit。企业组织与软件工程的策略 战略 趋势 原则 attilax 大总结
    atitit. 管理哲学 大毁灭 如何防止企业的自我毁灭
    Atitit.java的浏览器插件技术 Applet japplet attilax总结
    Atitit.jquery 版本新特性attilax总结
    Atitit. 软件开发中的管理哲学一个伟大的事业必然是过程导向为主 过程导向 vs 结果导向
    (转)获取手机的IMEI号
  • 原文地址:https://www.cnblogs.com/azxsdcv/p/13964432.html
Copyright © 2011-2022 走看看