边学边译Dive into python,中文版Dive into python,深入Python(二)

第二章.你的第一个Python程序

   你知道很多其它的类似的编程语言介绍书籍,通常都会一步一步的建立一个程序,直到最后其完成,就是一个完整的程序了。在这里,我们用另一种方式来介绍Python,让我们跳过原先那些老套的做法。

2.1入门

    这是一个完整的并且可以正常运行的Python程序。

    它也许会使你根本无法理解。但是不用担心,我将一行一行的解释他。只要通过一次阅读,你就可以做你想做的任何事了。

例如2.1odbchelp.py

如果你还没有准备好,你可以从http://diveintopython.org/download/diveintopythonexamples5.4.zip下载这个例子以及其它关于本书的例子。

def buildConnectionString(params):

"""Build a connection string from a dictionary of parameters.

Returns string."""

return ";".join(["%s=%s" % (k, v) for k, v in params.items()])

if __name__ == "__main__":

myParams = {"server":"mpilgrim", /

"database":"master", /

"uid":"sa", /

"pwd":"secret" /

}

print buildConnectionString(myParams)

 

现在让我们运行它,看看会发生什么。

注:

       1、在Windows上的ActivePython IDE环境下,你可以选择File>Run...(CtrlR)来运行你编辑的Python程序文件。输出将会显示在用户界面里。

       2、在Mac OS上的Python IDE环境下,你可以选择Python>Run window... (CmdR)来运行你编辑的Python程序文件。但是要注意的是,第一次使用时必须进行一次配置,在IDE环境下打开一个.py文件,然后打开选项菜单,点击右上角的小黑三角,保证RUN as __main__选项被选中。这是每一个文件的设置,但是你只需设置一次就可以了。

       3、在UNIX兼容系统下,包括Mac OS X,你可以使用下面的命令行来运行它:

Python odbchelp.py

 

odbchelp.py的运行结果会显示如下:

server=mpilgrim;uid=sa;database=master;pwd=secret

 

2.2函数声明

    Python和其它许多语言一样也有函数,但是不像需要将声明特意放在.hC++或者将程序分为interface/implementation两个部分的Pascal。只要你需要使用函数,你当时就可以声明它,就像这样:

def buildConnectionString(params):

如上面的程序,从关键词def开始就是声明,后面紧跟着函数的名字,再其后就是括号中的形式参数(arguments,以后简称为形参),可以有多个形参,形参间用逗号(‘,’)隔开。

    同样的上面的函数声明中并没有定义函数的返回类型。Python不需要对它们返回值进行事先的类型声明,也不指定它们是否有返回值。事实上每个Python都有一个返回值,如果函数执行中声明了返回值,那么它将返回那个值。如果没有在函数体内声明返回值,它将返回一个Python类型的空值――None

    Visual Basic中,函数以Function开始声明,并且其有返回值;而过程则以Sub开始声明,并且其没有返回值。在Python中,没有过程的概念,所有的都是函数,并且都有返回值(默认是None),所有的函数都从def开始。

    Python中变量不需要指定类型,像形参啊,程序里啊都不需要指明数据类型。Python的变量类型由其内部机制自动跟踪和控制。

    JavaC++以及其它一些静态数据类型语言中,你必须指明函数的返回类型,变量的类型,以及形参等地类型。在Python中,你无需对任何对象指定明确的类型。基于你给变量所附的值,系统内部会自动的进行类型的调整和跟踪。

 

2.2.1 P ython数据类型和其它语言数据类型之比较

    一位博学的学者告诉我如下面的python数据类型和其它语言数据类型的比较:

静态类型语言:

    这种语言在编译时确定类型。大多数静态类型语言明确要求,在你使用变量之前,必须要对变量的类型进行明确声明。JavaC就是静态类型语言。

动态类型语言:

    这种语言相对于静态类型语言而言,其在执行时确定数据类型。VBScriptPython都是这种类型的语言,因为它们在你第一次给变量付值时给定变量的类型。

强类型语言:

    这种语言总是强迫声明类型。JavaPython都是强类型语言,如若你有一个整形变量在你明确的转换它之前,你不能将其看作是一个字符串来操作。

弱类型语言:

    这种语言相对于强类型语言而言,对类型可能是视而不见。VBScript就是弱类型语言。在VBScript中,你可以在没有任何转换操作的情况下,将一个字符串‘ 12’ 和一个整形数字3进行连接运算得到字符串‘ 123’ 或者整形数字123

 

    所以Python是介于动态语言和强类型语言之间的一种语言。

2.3 函数文档

    你可以使用一个注释(doc String文档字符串)来说明一个函数的功能。

    例如2.2:声明buildConnectionString函数的文档字符串

def buildConnectionString(params):

"""Build a connection string from a dictionary of parameters.

Returns string."""

 

    三重引号代表一个多行的注释。在两部分引号间的所有部分,都是注释。内容通常包括:函数的返回类型和使用方法。你可以在任何地方用它们。但是你将在定义文档字串的地方多次的见到它们。

    三重引号是一种简单的定义注释的方法,就像Perl中的qq/……/一样。所有在两组三重引号间的部分都是函数的注释,说明函数的用途或者怎么用。如果需要一个注释,就必须事先在函数中声明它(通常是在函数声明那一行最后的“:”下一行)。你无需太多技巧来添加注释,但是您最好能在你声明函数之后加上它。也许你在其它编程语言里也见到过这样的规范,但是我给你一个Python的理由:函数注释(doc String)在程序运行时,可以像函数属性一样来使用。

    许多Python的集成开发环境都使用注释(doc String)来提供上下文关联文档。当你键入一个函数的名字时,它的注释就会像工具提示一样浮在一旁。这样就能提供一个很好的帮助,但是前提是你写着良好的函数注释。

 

阅读更多的关于函数注释的文档:

· PEP 257 (http://www.python.org/peps/pep−0257.html) defines doc string conventions.

·Python Style Guide (http://www.python.org/doc/essays/styleguide.html) discusses how to write a good docstring.

· Python Tutorial (http://www.python.org/doc/current/tut/tut.html) discusses conventions for spacing in docstrings (http://www.python.org/doc/current/tut/node6.html#SECTION006750000000000000000).

 

2.4 所有的东西都是对象

你没有忘记我刚才说函数的属性吧!那些属性可以在运行时直接被使用:

Python里,一个函数就和其他的东西一样,是一个对象。

打开你喜欢的Python IDE,然后按照下面的例子去做。

例如2.3 访问buildConnectionString函数的注释:

>>> import odbchelper                                   1

>>> params = {"server":"mpilgrim", "database":"master", "uid":"sa", "pwd":"secret"}

>>> print odbchelper.buildConnectionString(params)      2

server=mpilgrim;uid=sa;database=master;pwd=secret

>>> print odbchelper.buildConnectionString.__doc__      3

Build a connection string from a dictionary

Returns string.

 

1、第一行像一个模块一样将odbchelper程序引用(import)进来――你可以像这样交互式的使用已有的大段的代码或者一个大的Python程序。(你可以在第四章Python多模块编程中看到范例)。一次引用声明,你就可以使用它的说有共有函数、类或者属性。并且你可以在你的IDE中,在一个模块里调用另一个模块。这是一种非常重要的方法,在后面的章节我们会详细介绍它;

2、如果你要调用模块重的函数,你需要将模块名写上。不能只写buildConnectionString而要写成odbchelper.buildConnectionString。如果你原先使用过Java语言编程,你会感觉这非常亲切;

3、像你以往那样,我们替换调用的部分,我么来调用函数的一个属性:__doc__。在Python中使用引用(import)的应用和在Perl中很像,一旦你引用了一个Python的模块,在后续的使用中要访问模块中的函数,只需要像这样就可以了:module.function。而在Perl中,一旦你引用了一个模块进来,你只要像这样调用:module::function

2.4.1 引入搜索路径

    在进一步深入之前,我要先提一下库文件(library)的搜索路径的问题。当你试图引入模块时,Python将会去搜索几个特定的地方。这些地方被记录在sys.path文件中。它就是一张列表,你可以很容易的查看它,而且可以使用标准的列表方法来修改它。(在这一章的稍后部分我们将更多的介绍它)。

例如2.4 引入搜索路径

>>> import sys                                  1

>>> sys.path                                    2

['', '/usr/local/lib/python2.2', '/usr/local/lib/python2.2/plat−linux2',

'/usr/local/lib/python2.2/lib−dynload', '/usr/local/lib/python2.2/site−packages',

'/usr/local/lib/python2.2/site−packages/PIL', '/usr/local/lib/python2.2/site−packages/piddle']

>>> sys                                         3

<module 'sys' (built−in)>

>>> sys.path.append('/my/new/path')         4

 

1、引入系统文件所有的可用的函数和属性;

2、sys.path是当前的应用路径的目录文件,里面定义了当前所用的全部搜索路径。(你将看到你的系统的默认路径,以及你所使用的Python的安装路径)当你视图引入某个模块时,Python将会通过这个目录字典来匹配.py文件和模块的名称。

3、事实上,我撒谎了。实际上比那更复杂,并不是所有的模块都在.py文件里。一些类似sys这样的模块被直接定义建立在模块中(builtin modules),它们实际上是属于Python自身的一部分,builtin modules实际上就像是正常的模块,但是Python源代码里并没有用到它们,因为它们根本就不在Python的源码中。(模块sys是用C编写的)。

4、你可以将新的目录添加到sys.path搜索路径当中,并且添加之后Python将在你试图引入那个目录下的模块下时认出那个目录,在整个Python的运行期间其效果都会持续。(我将在第三章介绍更多的有关添加和模块列表的问题)。

 

2.4.2 对象是什么?

    Python中任何事物都是对象,而且差不多每个事物都有属性和方法。所有的函数都有一个属性“__doc__”。用来返回用户在源代码中定义函数时的注释。和所有的函数一样,sys模块也是对象,其中有个属性是Path

    尽管如此,还是有成堆的问题。比如:对象是什么?不同的语言里对对象的定义就有所不同。一些呢,说所有的对象必须有属性和方法;另一些,则说所有的对象都有子集(subclassable)。

    Python中,对对象没有严格的定义,一些对象既没有属性也没有方法(第三章将会更详细的介绍),并不是所有的对象都有子集(第五章将会更详细的介绍)。但是所有的见到的东西都是对象,它们能够作为值付值给变量或者通过函数的参数传递给函数(第四章将会更详细的介绍)。

    这就是为什么我在的一时间强调它的原因,你决不能错过它。Python中所有的事物都是对象,字符串是对象、列表是对象、函数是对象、连模块也是对象。

如果要了解更多请访问:

·Python Reference Manual (http://www.python.org/doc/current/ref/) explains exactly what it means to say thateverything in Python is an object (http://www.python.org/doc/current/ref/objects.html), because some people are pedantic and like to discuss this sort of thing at great length.

·eff−bot (http://www.effbot.org/guides/) summarizes Python objects(http://www.effbot.org/guides/python−objects.htm).

2.5 代码缩进

    Python的函数声明没有明确的起始和结束标志,也没有用花括号将其扩起来。一切就只是简单的一个“:”号和其后缩进的代码。

例如2.5 缩进了的BuildConnictionString函数的代码

def buildConnectionString(params):

"""Build a connection string from a dictionary of parameters.

Returns string."""

return ";".join(["%s=%s" % (k, v) for k, v in params.items()])

 

    代码块被自动的缩进,通过这些缩进的代码块,我知道函数的部分,IF语句的部分,FOR循环的部分,While循环的部分。缩进表示开始,而没有缩表示结束。无需其它的花括号、括号或者关键字。这些缩进的空格意义重大,它们保持着代码的风格,格式的统一。一个简单的例子,函数的代码包含了注释文档,在其前面有四个空格,注释文档不需要那四个空格,而是为了表明它是这个函数的一部分,为了保持一致,其它函数内所有的行前都加了四个空格。在外部的第一行就是函数,没有锯齿状的突起。

例如2.6 IF语句的缩进式声明

def fib(n):                                     1

print 'n =', n                                  2

if n > 1:                                       3

return n * fib(n − 1)

else:                                           4

print 'end of the line'

return 1

1、这是一个缩进式的函数声明,名字是fib,有一个参数n,下面缩进的部分就是函数体;

2、Python中要向屏幕输出是非常容易的,只要使用print语句就可以了。Print语句可以向屏幕打印任何本地数据类型,包括字符串型、整形、字典型、链表型等等。比如链表型,你可以混合几种类型在链表中,然后再让print将它打印在屏幕上。你只需将它们用逗号隔开,传递给一个链表,之后在Print后直接跟上这个链表变量,所有的元素都会排成一行被打印在屏幕上,而且中间是空格隔开的(链表中分隔元素的逗号不会被打印)。例如用5这个值来调用fib的话,将会显示“n5”;

3、IF语句块,如果条件为真,将会执行“IF”下面缩进的语句块,如果是其它假值,就会去执行Else语句块;

4、当然IF语句可以包含多行的语句块,就像这里的else语句块,他包含了两行语句,它也可以包含更多。对于语句块没有其它更多特别的要求,就只是简单的缩进。在你整个编程中,标记语句块的方法就是缩进和前进。

Fortran语言中,还有一些诸如首字母大写之类的建议,但不论怎样,你很快就会发现使用缩进的好处。一个最大的好处是,它使Python的程序看起来风格一致,便于自己与他人阅读,提高了程序的可维护性,也方便了你阅读别人的代码。

Python使用回车来分隔语句,使用“:”号和缩进来分割语句块;而C++Java使用“;”号来分隔语句,使用“{}”来分割语句块。

需要了解更多请访问:

·Python Reference Manual (http://www.python.org/doc/current/ref/) discusses cross−platform indentationissues and shows various indentation errors (http://www.python.org/doc/current/ref/indentation.html).

· Python Style Guide (http://www.python.org/doc/essays/styleguide.html) discusses good indentation style.

2.6 测试模块

Python的模块对象有一些特殊的属性。通过它,你可以很方便的测试你编写的模块。这是一个使用“if __name__”的小技巧的例子:

if __name__ == "__main__":

在测试之前给你一些好的建议和资料:首先,之后的语句不需要用花括号;其次,If语句在冒号处结束,下一行跟着缩进的代码块。

C语言一样,“==”用来比较,“=”用来付值。不同于C的是,Python不支持在一行即比较又付值,所以这样就不会发生意想不到的付值比较。

那么这条IF语句到底有什么特别之处呢?模块也是对象,所有的模块对象都有一个内建的属性“__name__”,你依靠它来决定你如何使用模块。如果你引入模块,那么__name__的值就是模块文件的名字(不包括路径和扩展名)。但是如果你想让模块像独立的程序一样运行,那么__name__将会被赋予一个特定的值“__main__”。

>>> import odbchelper

>>> odbchelper.__name__

'odbchelper'

    知道了这些,你就可以决定一组测试,将模块的测试语句加入这条if语句之后。当你直接运行模块时,__name__的值是__main__,测试被运行。当你引入这个模块时,__name__的值是模块自己的名字,这样就可以很容易的开发和调试新的模块并且很容易的将它们整合在一个大的工程里。

    MacPython上还要一些其它的特别的设置。才能让这条if语句正常运行。打开模块选项菜单(module's options menu)单击右上角的小黑箭头,确保Run as __main__被选中。

了解更多引入模块的问题请浏览:

· Python Reference Manual (http://www.python.org/doc/current/ref/) discusses the low−level details ofimporting modules (http://www.python.org/doc/current/ref/import.html).

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值