本篇文章给大家带来的内容是关于Python函数局部变量如何执行?浅析python函数变量的应用 ,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。
前言
这两天在 CodeReview 时,看本文来源[email protected]搞@^&代*@码2网到这样的代码
# 伪代码import somelibclass A(object): def load_project(self): self.project_code_to_name = {} for project in somelib.get_all_projects(): self.project_code_to_name[project] = project ...
意图很简单,就是将 somelib.get_all_projects
获取的项目塞入的 self.project_code_to_name
然而印象中这个是有优化空间的,于是提出调整方案:
import somelibclass A(object): def load_project(self): project_code_to_name = {} for project in somelib.get_all_projects(): project_code_to_name[project] = project self.project_code_to_name = project_code_to_name ...
方案很简单,就是先定义局部变量 project_code_to_name
,操作完,再赋值到self.project_code_to_name
。
在后面的测试,也确实发现这样是会好点,那么结果知道了,接下来肯定是想探索原因的!
局部变量
其实在网上很多地方,甚至很多书上都有讲过一个观点:访问局部变量速度要快很多,粗看好像好有道理,然后又看到下面贴了一大堆测试数据,虽然不知道是什么,但这是真的屌,记住再说,管他呢!
但是实际上这个观点还是有一定的局限性,并不是放诸四海皆准。所以先来理解下这句话吧,为什么大家都喜欢这样说。
先看段代码理解下什么是局部变量:
#coding: utf8a = 1def test(b): c = 'test' print a # 全局变量 print b # 局部变量 print c # 局部变量test(3)
# 输出13test
简单来说,局部变量就是只作用于所在的函数域,超过作用域就被回收
理解了什么是局部变量,就需要谈谈 Python 函数 和 局部变量 的爱恨情仇,因为如果不搞清楚这个,是很难感受到到底快在哪里;
为避免枯燥,以上述的代码来阐述吧,顺便附上 test 函数执行 的 dis 的解析:
# CALL_FUNCTION 5 0 LOAD_CONST 1 ('test') 3 STORE_FAST 1 (c) 6 6 LOAD_GLOBAL 0 (a) 9 PRINT_ITEM 10 PRINT_NEWLINE 7 11 LOAD_FAST 0 (b) 14 PRINT_ITEM 15 PRINT_NEWLINE 8 16 LOAD_FAST 1 (c) 19 PRINT_ITEM 20 PRINT_NEWLINE 21 LOAD_CONST 0 (None) 24 RETURN_VALUE
在上图中比较清楚能看到 a、b、c 分别对应的指令块,每一块的第一行都是 LOAD_XXX
,顾名思义,是说明这些变量是从哪个地方获取的。
LOAD_GLOBAL
毫无疑问是全局,但是 LOAD_FAST
是什么鬼?似乎应该叫LOAD_LOCAL
吧?
然而事实就是这么神奇,人家就真的是叫 LOAD_FAST
,因为局部变量是从一个叫 fastlocals
的数组里面读,所以名字也就这样叫了(我猜的)。
那么主角来了,我们要重点理解这个,因为这个确实还挺有意思。
Python 函数执行
Python 函数的构建和运行,说复杂不复杂,说简单也不简单,因为它需要区分很多情况,比方说需要区分 函数 和 方法,再而区分是有无参数,有什么参数,有木有变长参数,有木有关键参数。