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房间号,并没有对应到一个房间。是在下面才存在的,此刻并不存在。
所以报错了,函数就是一种?“变量”。
?```
原文:https://blog.51cto.com/15149862/2677932