注意,我们在print语句的结尾使用了一个 逗号 来消除每个print语句自动打印的换行符。这样
做有点难看,不过确实简单有效。
print # prints a blank line
注意,没有返回值的return语句等价于return None。None是Python中表示没有任何东西的特殊
类型。例如,如果一个变量的值为None,可以表示它没有值。
除非你提供你自己的return语句,每个函数都在结尾暗含有return None语句。通过运行print
someFunction(),你可以明白这一点,函数someFunction没有使用return语句,如同:
def someFunction():
pass
pass语句在Python中表示一个空的语句块。
切片操作符中的第一个数(冒号之前)表示切片开始的位置,第二个数(冒号之后)表示切片
到哪里结束。如果不指定第一个数,Python就从序列首开始。如果没有指定第二个数,则
Python会停止在序列尾。注意,返回的序列从开始位置 开始 ,刚好在 结束 位置之前结束。即
开始位置是包含在序列切片中的,而结束位置被排斥在切片外。
这样,shoplist[1:3]返回从位置1开始,包括位置2,但是停止在位置3的一个序列切片,因此返
回一个含有两个项目的切片。类似地,shoplist[:]返回整个序列的拷贝。
你可以用负数做切片。负数用在从序列尾开始计算的位置。例如,shoplist[:-1]会返回除了最后
一个项目外包含所有项目的序列切片。
使用Python解释器交互地尝试不同切片指定组合,即在提示符下你能够马上看到结果。序列的
神奇之处在于你可以用相同的方法访问元组、列表和字符串。
索引同样可以是负数,在那样的情况下,位置是从序列尾开始计算的。因此,shoplist[-1]表示
序列的最后一个元素而shoplist[-2]抓取序列的倒数第二个项目。
我们使用加法操作符来 级连 字符串,即把两个字符串连接在一起返回一个新的字符串。
zip命令有一些选项和参数。-q选项用来表示zip命令安静地工作。-r选项表示zip命令对目录递
归地工作,即它包括子目录以及子目录中的文件。两个选项可以组合成缩写形式-qr。选项后
面跟着待创建的zip归档的名称,然后再是待备份的文件和目录列表。我们使用已经学习过的
字符串join方法把source列表转换为字符串。
我们使用os.system函数 运行 命令,利用这个函数就好像在 系统
给Windows用户的注释
你可以把source列表和target目录设置成任何文件和目录名,但是在Windows中你得小心一些。
问题是Windows把反斜杠(\)作为目录分隔符,而Python用反斜杠表示转义符!
所以,你得使用转义符来表示反斜杠本身或者使用自然字符串。例如,使用'C:\\Documents'或
r'C:\Documents'而不是'C:\Documents'——你在使用一个不知名的转义符\D!
两个程序的大部分是相同的。改变的部分主要是使用os.exists函数检验在主备份目录中是否有
以当前日期作为名称的目录。如果没有,我们使用os.mkdir函数创建。
注意os.sep变量的用法——这会根据你的操作系统给出目录分隔符,即在Linux、Unix下它
是'/',在Windows下它是'\\',而在Mac OS下它是':'。使用os.sep而非直接使用字符,会使我们的
程序具有移植性,可以在上述这些系统下工作。
重要
我们创建这个备份脚本的过程是编写程序的推荐方法——进行分析与设计。开始时实施一个简
单的版本。对它进行测试与调试。使用它以确信它如预期那样地工作。再增加任何你想要的特
性,根据需要一次次重复这个编写-测试-使用的周期。记住“软件是长出来的,而不是建造
的”。
给C++/Java/C#程序员的注释
Python中的self等价于C++中的self指针和Java、C#中的this参考。
你一定很奇怪Python如何给self赋值以及为何你不需要给它赋值。举一个例子会使此变得清
晰。假如你有一个类称为MyClass和这个类的一个实例MyObject。当你调用这个对象的方法
MyObject.method(arg1, arg2)的时候,这会由Python自动转为MyClass.method(MyObject, arg1,
arg2)——这就是self的原理了。
这也意味着如果你有一个不需要参数的方法,你还是得给这个方法定义一个self参数。
给C++/Java/C#程序员的注释
__init__方法类似于C++、C#和Java中的 constructor 。
给C++/Java/C#程序员的注释
Python中所有的类成员(包括数据成员)都是 公共的 ,所有的方法都是 有效的 。
只有一个例外:如果你使用的数据成员名称以 双下划线前缀 比如__privatevar,Python的名称
管理体系会有效地把它作为私有变量。
这样就有一个惯例,如果某个变量只想在类或对象中使用,就应该以单下划线前缀。而其他的
名称都将作为公共的,可以被其他类/对象使用。记住这只是一个惯例,并不是Python所要求
的(与双下划线前缀不同)。
同样,注意__del__方法与 destructor 的概念类似。
为了使用继承,我们把基本类的名称作为一个元组跟在定义类时的类名称之后。然后,我们注
意到基本类的__init__方法专门使用self变量调用,这样我们就可以初始化对象的基本类部分。
这一点十分重要——Python不会自动调用基本类的constructor,你得亲自专门调用它。P78
我们还观察到我们在方法调用之前加上类名称前缀,然后把self变量及其他参数传递给它。
注意,在我们使用SchoolMember类的tell方法的时候,我们把Teacher和Student的实例仅仅作为
SchoolMember的实例。
另外,在这个例子中,我们调用了子类型的tell方法,而不是SchoolMember类的tell方法。可以
这样来理解,Python总是首先查找对应类型的方法,在这个例子中就是如此。如果它不能在导
出类中找到对应的方法,它才开始到基本类中逐个查找。基本类是在类定义的时候,在元组之
中指明的。
一个术语的注释——如果在继承元组中列了一个以上的类,那么它就被称作 多重继承 。
首先,我们通过指明我们希望打开的文件和模式来创建一个file类的实例。模式可以为读模式
('r')、写模式('w')或追加模式('a')。事实上还有多得多的模式可以使用,你可以使用
help(file)来了解它们的详情。P80
我们首先用写模式打开文件,然后使用file类的write方法来写文件,最后我们用close关闭这个文
件。
接下来,我们再一次打开同一个文件来读文件。如果我们没有指定模式,读模式会作为默认的
模式。在一个循环中,我们使用readline方法读文件的每一行。这个方法返回包括行末换行符
的一个完整行。所以,当一个 空的 字符串被返回的时候,即表示文件末已经到达了,于是我
们停止循环。
注意,因为从文件读到的内容已经以换行符结尾,所以我们在print语句上使用逗号来消除自动
换行。最后,我们用close关闭这个文件。
首先,请注意我们使用了import..as语法。这是一种便利方法,以便于我们可以使用更短的模块
名称。在这个例子中,它还让我们能够通过简单地改变一行就切换到另一个模块(cPickle或者
pickle)!在程序的其余部分的时候,我们简单地把这个模块称为p。P81
为了在文件里储存一个对象,首先以写模式打开一个file对象,然后调用储存器模块的dump函
数,把对象储存到打开的文件中。这个过程称为 储存 。
接下来,我们使用pickle模块的load函数的返回来取回对象。这个过程称为 取储存 。
repr函数用来取得对象的规范字符串表示。反引号(也称转换符)可以完成相同的功能。注
意,在大多数时候有eval(repr(object)) == object。
>>> i = []
>>> i.append('item')
>>> `i`
"['item']"
>>> repr(i)
"['item']"
基本上,repr函数和反引号用来获取对象的可打印的表示形式。你可以通过定义类的__repr__
方法来控制你的对象在被repr函数调用的时候返回的内容。