Python也许很友好,但它也容易弄得一团槽
作者 | Ari Joury
译者 | 王德朕
审校 | Noe
无论是行业领袖还是学术研究人员,都吹捧Python是编程新手最好的语言之一。他们没有错,但这并不意味着Python不会让编程新手们感到困惑。
以动态类型为例,看起来令人惊讶,Python 可以自己计算出变量可能获得的值类型,而且不需要浪费一行代码来声明类型,这样更快。
一开始是这样的,然后你在某一行搞砸了,继而导致你的整个项目在运行之前就崩溃了。
公平地说,其它语言许多都使用动态类型,但对于 Python 来说,这仅仅是一个糟糕清单的开始。
隐式声明变量会使得代码变得一团糟
几年前,当我开始攻读博士学位时,我想进一步开发一个由同事编写的现有软件,我了解它的基本原理,甚至我的同事写了一篇关于它的文档。
但我仍然需要阅读成千上万行的Python代码,以确保我知道每部分代码做了什么,从而可以把我想到的新功能放在那里,这就是问题所在......
整个代码中到处都是未被声明的变量,为了理解每个变量的用途,我必须在整个文件中搜索它,更常见的是在整个项目中搜索它。
还有一个复杂的情况,变量通常在函数内部被调用,但是当函数被调用时,又会有其他的东西被调用……还有一个情况,一个变量可以与一个类交织在一起,这个类与另一个类的另一个变量相关联,而另一个类又影响着一个完全不同的类……你明白了吧。
有这种经历的不止我一个,《Python之禅》中明确表示,显式要比隐式好,但是在Python中做隐式变量太容易了,特别是在大型项目中,很快就会遇到麻烦。
可变类型无处不在--甚至在函数中也是如此
在Python中,你可以通过提供默认值来定义具有可选参数的函数,不必再显式声明,像这样:
def add_five(a, b=0):
return a b 5
我知道这是个闹着玩的例子,但是你现在可以用一个或者两个参数来调用这个函数,它还是可以工作的:
add_five(3) # 返回 8
add_five(3,4) # 返回 12
它能运行,是因为表达式 b = 0将 b 定义为一个整数,而整数是不可变的:
def add_element(list=[]):
list.append("foo")
return list
add_element() # 返回 ["foo"],符合预期
到目前为止,一切正常,但是如果再次执行它会发生什么?
add_element() # returns ["foo", "foo"]! wtf!