淘客熙熙

主题:【原创】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 帖 引用 (帖内工具实现)
家园 写的好。提纲挈领,条理清晰!

加精,送花!

Python的cross-platform实际表现如何,是真正的platform neutral吗?

另外,和database 怎么talk呢?

Python有没有什么比较著名的成功case,什么样的App用它比较合适呢?

家园 深鞠一躬,献花三朵!

再次感叹西西河水之深!

家园 多谢欣赏。

我一直以来都是只在Linux下编程,只是最近才转到苹果的Mac,没有什么机会操心跨平台。Python在Linux/Unix以外的平台上似乎要稍微滞后一些。Windows因为不完全兼容POSIX,有些Python功能略有差异,特别是那些涉及到操作系统的部分,例如进程管理、文件系统访问等。但是那些诸如text processing,XML parsing、Internet protocols之类的功能还是非常platform neutral的。

Python有一个“正式”的关系型数据库接口标准,类似于ODBC或JDBC(http://python.org/peps/pep-0249.html)。几乎所有的数据库都有符合这个标准的接口包,如Postgresql、MySQL、Oracle、DB2、SQLite等等。

Python最著名的Killer Application应该是Zope(http://www.zope.org),一个非常成功的Content Management System。

Python适用范围非常广。我个人认为,最能发挥其优点的领域应该是类似数值分析和计算的领域。用Python做glue和user interface,用C和C++库做heavy lift,应该可以达到rapid application development的效果。

另外,好像有一些大型的游戏网站也是用Python做的。有一个Python的变种,叫Stackless Python(www.stackless.com),非常高效地实现了tasklet,据说比threading还要light weight,可以轻松地支持上万的concurrent users,非常玄妙。

元宝推荐:Highway,
家园 不敢当,不敢当。希望能帮上一星半点。
家园 更正及补充

首先,原文中把包的定义放到了模块上。

每一个Python源代码文件就是一个模块(module)。当一个或多个模块放在一个目录下,这个目录包含一个名为__init__.py的文件,并且这个目录起始于某个模块搜索路径(search path),那么这个目录就是一个包(package)。

比如说,一个HR软件,有employee.py、timesheet.py、rate.py、commission.py等等。如果我们把这些文件放到目录/usr/lib/python/HR/payroll下,在这个目录下产生一个__init__.py文件,然后把/usr/lib/python/加入到Python的模块搜索路径表中,我们就有了一个名为“HR.payroll”的包。当要使用这个包中的代码,例如类Employee,我们可以引入employee模块:

import HR.payroll.employee

在这行代码之后,定义在employee模块中的类Employee及其非私有成员和方法就被引入了当前模块中。当然,如果还有其他类或free functions,也一并被引入了当前模块。

其次,Python还有functional programming languages的某些特征。Python支持lambda,也就是在call site即时定义的无名函数,Perl称为closure。Python还有一些非常有趣和高效的处理sequence的内置函数。如:

[vec1[i]*vec2[i] for i in range(len(vec1))]返回一个list,其中每个元素是vec1和vec2对应元素的乘积。再如:map( lambda (x): x*x, [1,2,3] )得到一个list,[1,4,9]。

家园 您的文章让我受益匪浅,不过我这还有几个问题!

我刚开始学,可能问题都很基础,还请您别见笑,不吝赐教!

1。bubble-sort,merge-sort,quick-sort是什么区别?

2。linear rekursiv ,endrekursiv,baumrekursion,geschachtelte baumrekursion 的区别

3。o schreibweise是什么意思,应该怎么用呢

再次感谢

家园 您这是德语吧?

1:抱歉,我差不多都要把它们给忘光了,又不敢随便乱答。这些排序算法在计算机数据结构教材中应该都有提到。你也可以用Google查一下。

2:是关于递归(recursion)的?同样地,这是计算机数据结构和算法的典型内容。

3:这我可就完全摸不着头脑了。

题外话。如果你是一个计算机初学者,并且在用Python学数据结构和算法,我建议你换成Java或C++。因为Python对于数据类型的要求过宽松,我个人认为不适合计算机教学,特别是数据结构和算法这样的课程。你有可能把很多时间浪费在排除一些编译器就可以发现的低级错误上,例如,类型不匹配,或者赋值到了错误的变量名(Python会悄悄地为你自动生成一个新的变量而不是报警出错,你的程序的结果可能会完全不对)。

家园 关于排序(sort),有很多种算法,你感兴趣的话,

可以看看这个on-line的Demo,很生动的Java Applet,动画演示各种算法。这些算法的source code网上都有,你可以找来看看。

外链出处

家园 多谢好文,能不能谈谈Python在嵌入式系统的应用,

,以及最好的python入门书或资料。

家园 不好意思啊,一着急把德语都整出来了

尽量兄果然博学多才,以后再有问题还望继续赐教,感谢!

家园 对嵌入式系统开发了解不多。Python支持cross-platform compilation,

也就是说,可以把Python的编译器/解释器编译成为在目标系统下运行。具体怎么做就要看是什么目标系统和具体项目要求了。我知道有人已经尝试过了。用google搜索“python cross-platform”大概能找到一些有用的信息吧。

除了编译器/解释器外,Python还有一大堆的包(package)。如果对footprint要求较高,可以考虑把这些包去掉。虽然这些包都是包括在Python的每次发布里的,但并非每个包都是必须的。

我有O'Reilly出版的一本“Learning Python”,内容全面、翔实(封面是一只老鼠)。不过我认为太罗嗦了,没有突出Python简单,容易上手的优点。python.org有一些tutorials。当然google也可以帮你找到更多的有关学习python的资料。

家园 多谢!好的工具书确实不多。
家园 博学多才可称不上,只不过正好用过Python,有一些感受和经验罢了。
家园 偶买过一本巨厚的Python,还是原版的书

至今没翻过。。。

全看树展主题 · 分页 下页


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

Copyright © cchere 西西河