简明 Python 教程
说明:本文只是对《简明Python教程》的一个总结。请搜索该书查看真正的教程。
第3章 最初的步骤
1. Python是大小写敏感的。
2. 在#符号右面的内容都是注释
3. Python至少应当有第一行那样的特殊形式的注释。它被称作组织行——源文件的头两个字符是#!,后面跟着一个程序。这行告诉你的Linux/Unix系统当你执行你的程序的时候,它应该运行哪个解释器。
#!/usr/bin/python
4. Linux/Unix用户适用:chmod命令用来改变文件的模式 ,给系统中所有用户这个源文件的执行许可。然后我们可以直接通过指定源文件的位置来执行程序。我们使用./来指示程序位于当前目录。
chmod a+x helloworld.py
5. 用echo命令来显示PATH变量,用$给变量名加前缀以向shell表示我们需要这个变量的值。
把你选择的目录添加到PATH变量中去——这可以通过运行PATH=$PATH:/home/swaroop/mydir完成,
6. 如果你想要获取关于如print那样操作符的帮助,那么你需要正确的设置PYTHONDOCS环境变量。这可以在Linux/Unix中轻松地通过env命令完成。
env PYTHONDOCS=/usr/share/doc/python-docs-2.3.4/html/ python
第4章 基本概念
1. 可以用单引号指示字符串,就如同'Quote me on this'这样。所有的空白,即空格和制表符都照原样保留。
2. 在双引号中的字符串与单引号中的字符串的使用完全相同,例如"What's your name?"。
3 利用三引号,你可以指示一个多行的字符串。你可以在三引号中*的使用单引号和双
引号。例如:
'''This is a multi-line string. This is the first line.
This is the second line.
"What's your name?," I asked.
He said "Bond, James Bond."
'''
4. 用\'来指示单引号——注意这个反斜杠。现在你可以把字符串表示为'What\'s your name?'
另一个表示这个特别的字符串的方法是"What's your name?",即用双引号。类似地,要在双引号字符串中使用双引号本身的时候,也可以借助于转义符。另外,你可以用转义符\\来指示反斜杠本身。
5. 在一个字符串中,行末的单独一个反斜杠表示字符串在下一行继续,而不是开始一个新的行。例如:
"This is the first sentence.\
This is the second sentence."
等价于"This is the first sentence. This is the second sentence."
6. 如果你想要指示某些不需要如转义符那样的特别处理的字符串,那么你需要指定一个自然字符串。自然字符串通过给字符串加上前缀r或R来指定。例如r"Newlines are indicated by \n"。
7. Python允许你处理Unicode文本——你只需要在字符串前加上前缀u或U。例如,u"This is a Unicode string."。
8. 字符串是不可变的:这意味着一旦你创造了一个字符串,你就不能再改变它了。
9. 如果你把两个字符串按字面意义相邻放着,他们会被Python自动级连。
10. 在Python中没有专门的char数据类型。
11. 标识符的命名规则:
● 标识符的第一个字符必须是字母表中的字母(大写或小写)或者一个下划线(‘_’)。
● 标识符名称的其他部分可以由字母(大写或小写)、下划线(‘ _ ’)或数字(0-9)组成。
● 标识符名称是对大小写敏感的
12. 基本的类型是数和字符串。
13. Python把在程序中用到的任何东西都称为对象。
14. 使用变量时只需要给它们赋一个值。不需要声明或定义数据类型。
15. 物理行是你在编写程序时所看见的。逻辑行是Python看见的单个语句。Python假定每个物理行对应一个逻辑行。
16. 有时候,有一种暗示的假设,可以使你不需要使用反斜杠。这种情况出现在逻辑行中使用了圆括号、方括号或波形括号的时候。这被称为暗示的行连接。
17. 空白在Python中是重要的。事实上行首的空白是重要的。它称为缩进。在逻辑行首的空白(空格和制表符)用来决定逻辑行的缩进层次,从而用来决定语句的分组。
这意味着同一层次的语句必须有相同的缩进。每一组这样的语句称为一个块。
18. 不要混合使用制表符和空格来缩进,因为这在跨越不同的平台的时候,无法正常工作。强烈建议在每个缩进层次使用单个制表符或两个或四个空格。
第5章 运算符与表达式
1. 运算符
运算符 |
名称 |
说明 |
例子 |
+ |
加 |
两个对象相加 |
3 + 5得到8。'a' + 'b'得到'ab'。 |
- |
减 |
得到负数或是一个数减去另一个数 |
-5.2得到一个负数。50 - 24得到26。 |
* |
乘 |
两个数相乘或是返回一个被重复若干次的字符串 |
2 * 3得到6。'la' * 3得到'lalala'。 |
** |
幂 |
返回x的y次幂 |
3 ** 4得到81(即3 * 3 * 3 * 3) |
/ |
除 |
x除以y |
4/3得到1(整数的除法得到整数结 果)。4.0/3或4/3.0得到 1.3333333333333333 |
// |
取整除 |
返回商的整数部分 |
4 // 3.0得到1.0 |
% |
取模 |
返回除法的余数 |
8%3得到2。-25.5%2.25得到1.5 |
<< |
左移 |
把一个数的比特向左移一定数目 (每个数在内存中都表示为比特 或二进制数字,即0和1) |
2 << 2得到8。——2按比特表示为10 |
>> |
右移 |
把一个数的比特向右移一定数目 |
11 >> 1得到5。——11按比特表示为1011,向右移动1比特后得到101,即十进制的5。 |
& |
按位与 |
数的按位与 |
5 & 3得到1。 |
| |
按位或 |
数的按位或 |
5 | 3得到7。 |
^ |
按位异或 |
数的按位异或 |
5 ^ 3得到6 |
~ |
按位翻转 |
x的按位翻转是-(x+1) |
~5得到-6。 |
< |
小于 |
返回x是否小于y。所有比较运算符返回1表示真,返回0表示假。这分别与特殊的变量True和False等价。注意,这些变量名的大写。 |
5 < 3返回0(即False)而3 < 5返回1(即True)。比较可以被任意连接:3 < 5 < 7返回True。 |
> |
大于 |
返回x是否大于y |
5 > 3返回True。如果两个操作数都是数 字,它们首先被转换为一个共同的类 型。否则,它总是返回False。 |
<= |
小于等于 |
返回x是否小于等于y |
x = 3; y = 6; x <= y返回True。 |
>= |
大于等于 |
返回x是否大于等于y |
x = 4; y = 3; x >= y返回True。 |
== |
等于 |
比较对象是否相等 |
x = 2; y = 2; x == y返回True。x = 'str'; y ='stR'; x == y返回False。x = 'str'; y = 'str'; x == y返回True。 |
! |
不等于 |
比较两个对象是否不相等 |
x = 2; y = 3; x != y返回True。 |
not |
布 尔“非” |
如果x为True,返回False。如果x为False,它返回True。 |
x = True; not y返回False。 |
and |
布 尔“与” |
如果x为False,x and y返回False,否则它返回y的计算值。 |
x = False; y = True; x and y,由于x是 False,返回False。在这里,Python不会计算y,因为它知道这个表达式的值肯定是False(因为x是False)。这个现象称为短路计算。 |
or |
布 尔“或” |
如果x是True,它返回True,否则它返回y的计算值。 |
x = True; y = False; x or y返回True。短路 计算在这里也适用。 |
2. 运算符的优先级
运算符 |
描述 |
lambda |
Lambda表达式 |
or |
布尔“或” |
and |
布尔“与” |
not x |
布尔“非” |
in,not in |
成员测试 |
is,is not |
同一性测试 |
<,<=,>, >=,!=,== |
比较 |
| |
按位或 |
^ |
按位异或 |
& |
按位与 |
<<,>> |
移位 |
+,- |
加法与减法 |
*,/,% |
乘法、除法与取余 |
+x,-x |
正负号 |
~x |
按位翻转 |
** |
指数 |
x.attribute |
属性参考 |
x[index] |
下标 |
x[index:index] |
寻址段 |
f(arguments...) |
函数调用 |
(experession,...) |
绑定或元组显示 |
[expression,...] |
列表显示 |
{key:datum,...} |
字典显示 |
'expression,...' |
字符串转换 |
3. 尽管我们没有在'Area is'和变量area之间指定空格,Python自动在那里放了一个空格,这样我们就可以得到一个清晰漂亮的输出,而程序也变得更加易读(因为我们不需要担心输出之间的空格问题)
Area = 3
print 'Area is', area
Area is 3
第6章 控制流
1. 在Python中有三种控制流语句——if、for和while。
2.
if a == 1:
print 'aa'
elif a < 1:
print 'bb'
else:
print 'cc'
注意if、elif和else从句都在结尾处包含一个冒号——我们通过它告诉Python下面跟着一个语句块。
3. 在Python中没有switch语句。你可以使用if..elif..else语句来完成同样的工作(在某些场合,使用字典会更加快捷。)
4.
while a==1:
a=1
else:
print 'The while loop is over.'
while语句有一个可选的else从句
5.
for i in range(1, 5):
print i
else:
print 'The for loop is over'
range(1,5)给出序列[1, 2, 3, 4]。默认地,range的步长为1。如果我们为range提供第三个数,那么它将成为步长。例如,range(1,5,2)给出[1,3]。记住,range向上延伸到第二个数,即它不包含第二个数。
6. else部分是可选的。如果包含else,它总是在for循环结束后执行一次,除非遇到break语
句。
7. 对于break语句,如果你从for或while循环中终止,任何对应的循环else块将不执行
第7章 函数
1. 函数通过def关键字定义。def关键字后跟一个函数的 标识符 名称,然后跟一对圆括号。圆括号之中可以包括一些变量名,该行以冒号结尾。接下来是一块语句,它们是函数体。
def func(a):
return a*a
2. 使用global语句声明全局变量。
global x, y, z
3. 如果你的某个函数有许多参数,而你只想指定其中的一部分,那么你可以通过命名来为这些参数赋值——这被称作关键参数——我们使用名字(关键字)而不是位置(我们前面所一直使用的方法)来给函数指定实参。
这样做有两个优势 ——一,由于我们不必担心参数的顺序,使用函数变得更加简单了。二、假设其他参数都有默认值,我们可以只给我们想要的那些参数赋值。
def func(a, b=5, c=10): # 默认参数
print 'a is', a, 'and b is', b, 'and c is', c
func(3, 7)
func(25, c=24)
func(c=50, a=100)
4. pass语句在Python中表示一个空的语句块。
def someFunction():
pass
5. Python有一个很奇妙的特性,称为文档字符串,它通常被简称为docstrings 。DocStrings是一个重要的工具,由于它帮助你的程序文档更加简单易懂,你应该尽量使用它。你甚至可以在程序运行的时候,从函数恢复文档字符串!
文档字符串的惯例是一个多行字符串,它的首行以大写字母开始,句号结尾。第二行是空行,从第三行开始是详细的描述。强烈建议你在你的函数中使用文档字符串时遵循这个惯例。
可以使用__doc__(注意双下划线)调用func函数的文档字符串属性(属于函数的名称)。
def func(a):
'''Calculate square of a
The input is a number'''
return a*a
第8章 模块
1. 模块基本上就是一个包含了所有你定义的函数和变量的文件。为了在其他程序中重用模块,模块的文件名必须以.py为扩展名。
2. Python从0开始计数,而非从1开始。
3. 如果你想要直接输入argv变量到你的程序中(避免在每次使用它时打sys.),那么你可以使用from sys import argv语句。如果你想要输入所有sys模块使用的名字,那么你可以使用from sys import *语句
4. 当一个模块被第一次输入的时候,这个模块的主块将被运行。假如我们只想在程序本身被使用的时候运行主块,而在它被别的模块输入的时候不运行主块,我们该怎么做呢?这可以通过模块的__name__属性完成。
每个Python模块都有它的__name__,如果它是'__main__',这说明这个模块被用户单独运行,我们可以进行相应的恰当操作。
if __name__ == '__main__':
print 'This program is being run by itself'
else:
print 'I am being imported from another module'
5. 可以使用内建的dir函数来列出模块定义的标识符。标识符有函数、类和变量。
第9章 数据结构
1. 在Python中有三种内建的数据结构——列表、元组和字典。
2. list是处理一组有序项目的数据结构,即你可以在一个列表中存储一个序列的项目。在Python中,你在每个项目之间用逗号分割。
shoplist = ['apple', 'mango', 'carrot', 'banana']
shoplist.sort() # shoplist = ['apple', 'banana', 'carrot', 'mango']
使用列表的sort方法来对列表排序。需要理解的是,这个方法影响列表本身,而不是返回一个修改后的列表——这与字符串工作的方法不同。这就是我们所说的列表是可变的而字符串是不可变的 。
3. 元组和列表十分类似,只不过元组和字符串一样是不可变的,即你不能修改元组。元组通过圆括号中用逗号分割的项目定义。注意元组之内的元组不会失去它的身份。
一个空的元组由一对空的圆括号组成,如myempty = ()。然而,含有单个元素的元组就不那么简单了。你必须在第一个(唯一一个)项目后跟一个逗号,这样Python才能区分元组和表达式中一个带圆括号的对象。即如果你想要的是一个包含项目2的元组的时候,应该指明singleton = (2 , )。
zoo = ('wolf', 'elephant', 'penguin')
4. print语句可以使用跟着%符号的项目元组的字符串。定制可以是%s表示字符串或%d表示整数。
age = 22
name = 'Swaroop'
print '%s is %d years old' % (name, age) # Swaroop is 22 years old
5. 字典类似于你通过联系人名字查找地址和联系人详细情况的地址簿,即,我们把键(名字)和值(详细情况)联系在一起。注意,键必须是唯一的。
只能使用不可变的对象(比如字符串)来作为字典的键,可以把不可变或可变的对象作为字典的值。
6. 键值对在字典中以这样的方式标记:d = {key1 : value1, key2 : value2 }。注意它们的键/值对用冒号分割,而各个对用逗号分割,所有这些都包括在花括号中。
记住字典中的键/值对是没有顺序的。字典是dict类的实例/对象。
ab = { 'Swaroop' : 'swaroopch@byteofpython.info',
'Larry' : 'larry@wall.org',
'Matsumoto' : 'matz@ruby-lang.org',
'Spammer' : 'spammer@hotmail.com'
}
7. 列表、元组和字符串都是序列。序列的两个主要特点是索引操作符和切片操作符。索引操作符让我们可以从序列中抓取一个特定项目。切片操作符让我们能够获取序列的一个切片,即一部分序列。
索引同样可以是负数,在那样的情况下,位置是从序列尾开始计算的。因此,shoplist[-1]表示序列的最后一个元素,shoplist[-2]抓取序列的倒数第二个项目。
切片操作符是序列名后跟一个方括号,方括号中有一对可选的数字,并用冒号分割。注意这与你使用的索引操作符十分相似。记住数是可选的,而冒号是必须的。
切片操作符中的第一个数(冒号之前)表示切片开始的位置,第二个数(冒号之后)表示切片到哪里结束。如果不指定第一个数,Python就从序列首开始。如果没有指定第二个数,则Python会停止在序列尾。注意,返回的序列从开始位置开始,刚好在结束位置之前结束。即开始位置是包含在序列切片中的,而结束位置被排斥在切片外。
shoplist = ['apple', 'mango', 'carrot', 'banana']
# 索引操作
print 'Item 0 is', shoplist[0]
print 'Item 3 is', shoplist[3]
print 'Item -1 is', shoplist[-1]
print 'Item -2 is', shoplist[-2]
# 切片操作
print 'Item 1 to 3 is', shoplist[1:3]
print 'Item 2 to end is', shoplist[2:]
print 'Item 1 to -1 is', shoplist[1:-1]
print 'Item start to end is', shoplist[:]
8. 序列的神奇之处在于你可以用相同的方法访问元组、列表和字符串。
9. 如果你想要复制一个列表或者类似的序列或者其他复杂的对象(不是如整数那样的简单对象),那么你必须使用切片操作符来取得拷贝。
mylist = shoplist[:] # make a copy by doing a full slice
10. startwith方法是用来测试字符串是否以给定字符串开始。
11. in操作符用来检验一个给定字符串是否为另一个字符串的一部分。
12. find方法用来找出给定字符串在另一个字符串中的位置,或者返回-1以表示找不到子字符串。
13. str类也有以一个作为分隔符的字符串join序列的项目的整洁的方法,它返回一个生成的大字符串。
第11章 面向对象的编程
1. 类和对象是面向对象编程的两个主要方面。类创建一个新类型,而对象这个类的实例 。
2. 即便是整数也被作为对象(属于int类)。属于一个对象或类的变量被称为域。域和方法可以合称为类的属性。域有两种类型——属于每个实例/类的对象或属于类本身。它们分别被称为实例变量和类变量。
3. 类的方法与普通的函数只有一个特别的区别——它们必须有一个额外的第一个参数名称,但是在调用这个方法的时候你不为这个参数赋值,Python会提供这个值。这个特别的变量指对象本身,按照惯例它的名称是self。Python中的self等价于C++中的this指针。
4. 使用类名后跟一对圆括号来创建一个对象/实例。__init__方法在类的一个对象被建立时,马上运行。这个方法可以用来对你的对象做一些你希望的初始化。__init__方法类似于C++、C#和Java中的constructor。__del__在对象消逝的时候被调用。__del__方法与destructor的概念类似。
class Person:
def __init__(self, name):
self.name = name
def __del__(self):
pass
def sayHi(self):
print 'Hello, my name is', self.name
p = Person('Swaroop')
p.sayHi()
5. 有两种类型的域 ——类的变量和对象的变量。
类的变量由一个类的所有对象(实例)共享使用。只有一个类变量的拷贝,所以当某个对象对类的变量做了改动的时候,这个改动会反映到所有其他的实例上。(类似于C++中的static)
对象的变量由类的每个对象/实例拥有。因此每个对象有自己对这个域的一份拷贝,即它们不是共享的,在同一个类的不同实例中,虽然对象的变量有相同的名称,但是是互不相关的。
6. Python中所有的类成员(包括数据成员)都是公共的,所有的方法都是有效的。只有一个例外:如果你使用的数据成员名称以双下划线前缀比如__privatevar,Python的名称管理体系会有效地把它作为私有变量。
7. 一个子类型在任何需要父类型的场合可以被替换成父类型,即对象可以被视作是父类的实例,这种现象被称为多态现象。Python不会自动调用基本类的constructor,你得亲自专门调用它。
class SchoolMember:
def __init__(self, name):
self.name = name
class Teacher(SchoolMember):
def __init__(self, name, age):
SchoolMember.__init__(self, name)
self.age = age
第12章 输入/输出
1. import..as。这是一种便利方法,以便于我们可以使用更短的模块名称。
import cPickle as p
第13章 异常
1. 把所有可能引发错误的语句放在try块中,然后在except从句/块中处理所有的错误和异常。except从句可以专门处理单一的错误或异常,或者一组包括在圆括号内的错误/异常。如果没有给出错误或异常的名称,它会处理所有的错误和异常。对于每个try从句,至少都有一个相关联的except从句。
如果某个错误或异常没有被处理,默认的Python处理器就会被调用。它会终止程序的运行,并且打印一个消息。
2. 假如你在读一个文件的时候,希望在无论异常发生与否的情况下都关闭文件,可以使用finally块来完成。注意,在一个try块下,你可以同时使用except从句和finally块。如果你要同时使用它们的话,需要把一个嵌入另外一个。
第15章 更多Python的内容
1. 通过列表综合,可以从一个已有的列表导出一个新的列表。
listone = [2, 3, 4]
listtwo = [2*i for i in listone if i > 2] # [6, 8]
2. 当要使函数接收元组或字典形式的参数的时候,有一种特殊的方法,它分别使用*和**前缀。这种方法在函数需要获取可变数量的参数的时候特别有用。
如果在args变量前有*前缀,所有多余的函数参数都会作为一个元组存储在args中。如果使用的是**前缀,多余的参数则会被认为是一个字典的键/值对。
def powersum(power, *args):
'''Return the sum of each argument raised to specified power.'''
total = 0
for i in args:
total += pow(i, power)
return total
powersum(2, 3, 4) # 25
powersum(2, 10) # 100
3. lambda语句被用来创建新的函数对象,并且在运行时返回它们。注意,即便是print语句也不能用在lambda形式中,只能使用表达式。
def make_repeater(n):
return lambda s: s*n
twice = make_repeater(2)
print twice('word') # wordword
print twice(5) # 10
4 exec语句用来执行储存在字符串或文件中的Python语句。
exec 'print "Hello World"' # Hello World
5. eval语句用来计算存储在字符串中的有效Python表达式。
eval('2*3') # 6
6. assert语句用来声明某个条件是真的。当assert语句失败的时候,会引发一个AssertionError。
7. repr函数用来取得对象的规范字符串表示。反引号(也称转换符)可以完成相同的功能。注意,在大多数时候有eval(repr(object)) == object。