injector , 我从 ng 的文档中得知这个概念,之后去翻看源码时了解了一下这个机制的工作原理。感觉就是虽然与自己的所想仅差那么一点点,但就是这么一点点,让我感慨想象力之神奇。
先看我们之前代码中的一处函数定义:
var BoxCtrl = function($scope, $element){}
在这个函数定义中,注意那两个参数: $scope , $element ,这是两个很有意思的东西。总的来说,它们是参数,这没什么可说的。但又不仅仅是参数——你换个名字代码就不能正常运行了。
事实上,这两个参数,除了完成“参数”的本身任务之外,还作为一种语法糖完成了“依赖声明”的任务。本来这个函数定义,完整的写法应该像 AMD 声明一样,写成:
var BoxCtrl = ['$scope', '$element', function(s, e){}];
这样就很明显,表示有一个函数,它依赖于两个东西,然后这两个东西会依次作为参数传入。
简单起见,就写成了一个函数定义原本的样子,然后在定义参数的名字上作文章,来起到依赖声明的作用。
在处理时,通过函数对象的 toString() 方法可以知道这个函数定义代码的字符串表现形式,然后就知道它的参数是 $scope 和 $element 。通过名字判断出这是两个外部依赖,然后就去获取资源,最后把资源作为参数,调用定义的函数。
所以,参数的名字是不能随便写的,这里也充分利用了 js 的特点来尽量做到“反省”了。
在 Python 中受限于函数名的命名规则,写出来不太好看。不过也得利于反省机制,做到这点也很容易:
# -- coding: utf-8 --
def f(Ia, Ib):
print Ia, Ib
args = f.func_code.co_varnames
SRV_MAP = {
'Ia': '123',
'Ib': '456',
}
srv = {}
for a in args:
if a in SRV_MAP:
srv[a] = SRV_MAP[a]
f(**srv)