Python是一种解释性的编程语言。就象Java一样,源代码必须首先由编译器转换成字节瘁
(byte code),然后再由解释器来执行字节码。和Java不一样的是,Python的编译器和解释器
都是一个程序。因此,源代码也可以直接交给这个编译器/解释器来执行。其实,源代码还是先
转换成了字节码,只是没有存在硬盘上,而是直接执行了。某些情况下,这种方式要比Java的
“编辑-编译-修改-再编译-执行”方式效率要高,特别是在写一些小规模的程序时。
Python是一种面向对象的编程语言。所有的内置(built-in)数据类型都是类:整数(int)、
浮点(float)、串(string)、布尔(boolean)、mapping、sequence,等等。经常你
会看到一些老鸟写的程序里有类似这样的代码:idx = "book.txt".find("txt") 乍一看,怎么
字符串常量还能有方法呢?其实,如果想到Python的字符串常量也是其类型的实例(instance),
也就是对象,那么这样用当然也就不奇怪了。
在Python类定义中,类构造器(constructors)必须用 __init__命名,析构器(destructors)
必须用 __del__命名。Python类的构造器不会自动掉用父类的构造器,子类必须在其构造器中
显式地调用父类的构造器。子类可以选择调用父类构造器的时机,比C++和Java又要灵活一些。
相应地,子类的析构器也需要显式地调用父类的析构器。
Python使用引用计数(reference counting)来简化内存管理,程序员基本上不用关心
内存管理的问题,但是要注意避免循环引用(cyclic reference)。变量生成时,其所指对象
的引用计数为一。每次变量出现在等号的右边,或者出现在方法或函数调用实参表里,其所指对
象的引用计数加一。当一个变量out of scope的时候,其所指对象的引用计数会被减一。如果计
数值为零,对象的析构器会被调用。
Python同时还是一种过程式(procedural)的编程语言,有条件判断、循环、函数等常见的控制
结构。不像Java,类对Python程序不是必须的。一个程序可以写出来完全没有类的定义,从头到
尾都是free functions和函数调用(function calls)。这点上,Python和C++类似。
大概最有争议性的是Python对源代码格式的要求。不像C家族的编程语言,Python不是自由格式
的。Python的scope是靠行首缩进来界定的,而不是匹配的括号。比方说,如果一个类的定义起
始于第一列,那么,类中所有成员及方法必须出现在第一列以后,并且处于同一层次的语句必须
出现在相同的列上。这个特点的初衷是为了维护程序的可读性,也确实达成了目的。大部分的
Python源代码都是排列得整整齐齐的,风格基本接近。但我个人认为有一点矫枉过正了。
每一个Python源代码文件可以包含一个或多个的类、free functions。多个源文件在一个文件
系统目录(directory)下可以成为一个模块(module),只要这个目录中有一个名为
__init__.py的文件存在。这个文件甚至可以是空的。模块可以被其他Python代码引入
(import),用类似于Java的“import graphic.2D.text”。模块也是Python最常见的代码
重用形式。Python的编译器和解释器会在缺省的和指定的路径中搜索被引入的模块。
Python的名字空间有一点古怪,不太容易说清清楚。对于初学者来说,记住在函数和类方法中存
取全局变量是一定要事先用“global foo”声明。当然,尽量少用全局变量这个金科玉律对
python也是适用的。
随着Python编译器/解释器一起发行的有大概上百个模块,涵盖了从字符串匹配,xml parsing,
操作系统功能到电子邮件处理等等各个领域。由于这些模块大部分是由来自世界各地的Python使
用者贡献的,在早期也没有比较正式的命名规范,每个人都有自己的风格。对于习惯了Java严谨
命名规范的人来说,Python看起来就太不“专业”了。这应该也是其他open source软件的一个
特点吧,如果不是问题的话。