不入门Python是不可能不入门的,还不如先连连基本的字符串和运算操作,为数据清理搬砖积累点经验和微小技能。
今天学到Functions as Objects [Introduction to Computation and Programming Using Python, John V.Guttag 2013版]。竟然发现了一个跟R语言里类似的情况,Lexical Scope里的foo和foo()的区别
涉及的代码:
def applyToEach(L,f):
for i in range(len(L)):
L[i]=f(L[i])
L=[1,-2,3.33]
applyToEach(L,abs)
print(L)
书上本意是演示“函数本身以对象形式作为参数传递”的情况,f(l[I])是f(函数)后面加了参数框(),所以如果f本身就有括号,比如abs(),就应该输入去掉括号的形式,abs。
这个以及之后的int(转换成整数)照书输入没注意到,蒙混过关,但接下来我自己使用math.factorial()则出问题了
#此时L内的元素都已经转换成整数了
import math
applyToEach(L,math.factorial())
print(L)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-20-08858b6cb9e2> in <module>
1 import math
----> 2 applyToEach(L,math.factorial())
3 print(L)
4
TypeError: factorial() takes exactly one argument (0 given)
解释器报错说factorial()的参数出了问题,应该是正好1个,结果输入的是0个。
正确操作是删去(),就变成了applyToEach(L,math.factorial) 。
讨论:一个方法(函数)可以带括号也可以不带,括号是用于控制参数的,这个方法能不能正常运行只有在解释之后实时运行时才知道,这是Python和R的特质,估计也是很多其他动态语言如Ruby、Javascript的特征「请指正」。静态语言需要编译,编译之前(而不能等到运行时)需要确定方法/函数的返回类型因此都是用括号指明参数的(0到多个)。
Java不允许讲方法作为参数传递,但可以通过lamda表达简化相关语句。我暂时还没遇到lamda表达恰到好处的例子,看了几个演示性的例子觉得要么导致逻辑不够清晰降低了可维护性要么不易理解。