西西河

主题:【原创】Python简介 -- 请尽量

共:💬45 🌺35 新:
全看分页树展 · 主题
家园 【原创】Python简介

Python简介

首先,讲一下Python的创始人Guido van Rossum的一句名言:There is only one way to do it, the right way。这个思想对Python语言的出现和发展影响很大,这也是Python迷们经常放在嘴边的一句话。

Python是一种解释性的编程语言。就象Java一样,源代码必须首先由编译器转换成字节瘁(byte code),然后再由解释器来执行字节码。和Java不一样的是,Python的编译器和解释器都是一个程序。因此,源代码也可以直接交给这个编译器/解释器来执行。其实,源代码还是先转换成了字节码,只是没有存在硬盘上,而是直接执行了。某些情况下,这种方式要比Java的“编辑-编译-修改-再编译-执行”方式效率要高,特别是在写一些小规模的程序时。

Python程序的结构、设计与使用方法和“主流”的计算机编程语言还是很接近的。这是一个优点,降低了门槛,易于初学者上手。

Python是一种面向对象的编程语言。所有的内置(built-in)数据类型都是类:整数(int)、浮点(float)、串(string)、布尔(boolean)、mapping、sequence,等等。经常你会看到一些老鸟写的程序里有类似这样的代码:idx = "book.txt".find("txt") 乍一看,怎么字符串常量还能有方法呢?其实,如果想到Python的字符串常量也是其类型的实例(instance),也就是对象,那么这样用当然也就不奇怪了。

既然是面向对象的编程语言,当然就支持封装和继承。在Python里,类的成员和方法都是公开的(public)。如果变量名是由连续两个下划线(underscore)起头的,比如:__count,__copy_by_size等等,编译器在生成字节码时会把类型名加上,比如:__Employee_count。这通常被叫做“mangle”。其实,Python的“私有”成员更多是防止与子类的成员产生名字冲突,而不是试图控制对类成员和类方法的存取。在实际使用中,这种控制是很弱的,可以被轻易绕过。

Python没有“被保护”(protected)成员的概念。在实际使用中,程序员通常在变量名前加上一个下划线作为一种提示。这只是一种惯例,语言规则本身和编译器并不强制执行。

Python似乎对下划线情有独钟,很多地方都把下划线放在特殊位置上。在下面还会看到更多的例子。

Python的这种存取控制模式一般来说不会引起什么问题,但在大型的library或framework的项目中,有时还是会让人感到不便,特别是具有C++和Java背景的程序员会发现无法应用有些design patterns。

和所有其他面向对象语言一样,在子类中定义的非私有成员和方法重载父类中同名的成员和方法。和C++、Java不一样的是,在定义类方法时,对象实例(C++中的this)必须被显式地(explicitly)放在方法形参表的第一个。在C++中,这个对象实例是被编译器自动加上去的。另外,Python程序的惯例是用self,并且这个不由编译器强制。这和在C++和Java中,this是保留字是不同的。在调用类方法时,这个变量又不能出现在实参表里。这和C++与Java又一致了。

在Python类定义中,类构造器(constructors)必须用 __init__命名,析构器(destructors)必须用 __del__命名。Python类的构造器不会自动掉用父类的构造器,子类必须在其构造器中显式地调用父类的构造器。子类可以选择调用父类构造器的时机,比C++和Java又要灵活一些。相应地,子类的析构器也需要显式地调用父类的析构器。

Python程序中的变量没有固定的类型,也就是常说的动态类型。在一个变量out of scope之前,其所“包含”的值类型可以被改变。所以,Python程序中的变量也不用事先声明,随用随生成好了。这在写小程序的时候很方便,但是对于大一些的项目,特别是需要多个人合作完成的软件,就会带来麻烦,因为没有编译器来帮你发现使用未声明的变量,或是变量类型不符。通常的做法是在使用变量前检查其是否为“空”(None),因为第一次使用的变量总是指向“空”这个特殊的对象,直到被赋值。当然,这种检查会影响performance。对于类型不符,比较常见的办法是给变量一个可以看出其类型的名字,指望使用者能够注意。这就简直就是一个悖论,依靠人来防止因为人的不可靠而产生的错误。

Python使用引用计数(reference counting)来简化内存管理,程序员基本上不用关心内存管理的问题,但是要注意避免循环引用(cyclic reference)。变量生成时,其所指对象的引用计数为一。每次变量出现在等号的右边,或者出现在方法或函数调用实参表里,其所指对象的引用计数加一。当一个变量out of scope的时候,其所指对象的引用计数会被减一。如果计数值为零,对象的析构器会被调用。

Python有限度地支持运算符重载。比如说,可以为一个用户自定义的矩阵类型重载加、减、乘、除,那么使用这个矩阵类型的代码就可以用更加直观的+、-、*、/等操作符来直接进行矩阵的算术运算。

Python同时还是一种过程式(procedural)的编程语言,有条件判断、循环、函数等常见的控制结构。不像Java,类对Python程序不是必须的。一个程序可以写出来完全没有类的定义,从头到尾都是free functions和函数调用(function calls)。这点上,Python和C++类似。

Python的函数和类方法支持overload。因为变量是没有类型的,所有overload resolution只能靠区分形参数目。

Python支持异常(exceptions)。和C++、Java一样,Python的异常使得当前stack frame中所有的变量out of scope,并且中断程序的执行,将异常升级(escalate)。这点上和C++及Java类似。

大概最有争议性的是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语言自身外,其他语言也可以用来写模块,这体现了Python很强的可扩展性。最常见的是C和C++。其实,Python的很多基本模块就是用C写成的。通常来说,C写成的模块要比Python写的快很多,通常是几个数量级的区别。另外,很多的已有的C/C++动态库也可以通过这种办法成为Python的模块。这样,既增加了Python的应用范围,又把Python的易于使用和C/C++的高效、高性能就很好地结合起来了。这大概是Python日益流行的原因之一吧。

随着Python编译器/解释器一起发行的有大概上百个模块,涵盖了从字符串匹配,xml parsing,操作系统功能到电子邮件处理等等各个领域。由于这些模块大部分是由来自世界各地的Python使用者贡献的,在早期也没有比较正式的命名规范,每个人都有自己的风格。对于习惯了Java严谨命名规范的人来说,Python看起来就太不“专业”了。这应该也是其他open source软件的一个特点吧,如果不是问题的话。

此外,Python还可以被用作嵌入式的解释器(embedded interpretor)。Python的运行时环境runtime environment有很清晰的C接口,整个编译器/解释器可以被很容易地嵌入到C或者C++的程序中,加上上面所说的由Python到C的接口,Python就具有了类似微软的VBA的能力。这对大型的软件系统是很有吸引力的。OpenOffice就有一个Python接口。

在2.2版本发布后,Python语言本身的发展逐渐转向了对大型软件项目的支持。一些新的language features被加了进来,比如generator、类方法、静态方法、property、method decorator等等。Python community同时也非常注意借鉴其他编程语言的优点。

Python编译器/解释器的正是发行版本(released by Python.org and blessed by Guido van Rossum)是由C实现的。其实Python编译器/解释器还有其他语言的,如Java(Jython)、C#(IronPython)。另外,还有一帮人已经花了好几年时间试图写一个可以解释执行Perl和Python字节码的运行环境,叫Parrot。Perl 6已经决定采用它来作解释器了。

最后,Python这个名字来自于六十年代英国的一个很有名的喜剧系列Monty Python (http://www.bbc.co.uk/dna/h2g2/A687945)。据说Python语言的创造者是个great fan。

元宝推荐:Highway,

本帖一共被 1 帖 引用 (帖内工具实现)
全看分页树展 · 主题


有趣有益,互惠互利;开阔视野,博采众长。
虚拟的网络,真实的人。天南地北客,相逢皆朋友

Copyright © cchere 西西河