简明Python教程-读书笔记

《简明Python教程》读书笔记

使用《简明Python教程》漠伦翻译版
https://bop.mol.uno/
使用Python3.5.1

关于Python

简单、易于学习、自由且开放(FLOSS)、高级语言、跨平台性、解释性、面向对象、可扩展性、可嵌入性、丰富的库

在程序内部,Python会将源代码转换为称为字节码的中间形式,尔后再转换成你的电脑所使用的语,并运行它

安装

Linux

1
2
sudo apt install python3
python3 -V

第一步

通过Python运行程序有两种方法

  1. 使用交互式解释器提示符>>>
  2. 直接运行一个源代码python test.py

Python区分大小写

获取帮助

1
help('input')

最好使用引号,不使用引号有时会出错,比如help(return)
q退出

基础

  1. 注释:使用#
  2. 字面常量
  3. 数字:整数1、浮点数3.23``52.3E-4
  4. 字符串:字符串是不可变的
    • 单引号:所有引号中的空格、制表符保留原样(不是转义\t
    • 双引号:和单引号括起的字符串一样
    • 三引号:”””或’’’,多行字符串
  5. Python从0开始计数

字符串

字符串格式化

1
2
3
age = 20
name = 'Swaroop'
print('{0} was {1} years old when he wrote this book'.format(name,age))

不需要转换格式,数字可以不写

1
2
3
4
5
6
7
#对于浮点数'0.333'保留小数点(.)后三位
print('{0:.3f}'.format(1.0/3))
#使用下划线填充文本,并保持文字处于中间位置
#使用(^)定义'___hello___'字符串长度为11
print('{0:_^11}'.format('hello'))
#基于关键词输出'Swaroop wrote A Byte of Python',不能用{0}
print('{name} wrote {book}'.format(name='Swaroop',book='A Byte of Python'))

print会以\n结尾,通过end可以指定结尾方式

1
2
print('a',end='')
print('b',end=' ')

print(),连接字符串,且会自动加上空格

1
print('a','b')

字符串连接

1
name + 'is' + str(age) + 'years old'

不如格式化美观,容易出错,而且需要转换类型

转义字符

  1. \':单引号
  2. \n:换行
  3. \t:制表符
  4. 在一个字符串中,一个放置在末尾的反斜杠表示字符串将在下一行继续,但不会换行

原始字符串
rR,在处理正则表达式时应全程使用原始字符串

1
r'Newlines are indicated by \n'

变量

命名

  1. 第一个字符必须是字母表中的字母(大写ASCII字符或小写ASCII字符或Unicode字符)或下划线(_)。
  2. 标识符的其它部分可以由字符(大写 ASCII 字符或小写 ASCII 字符或 Unicode字符)、下划线(_)、数字(0~9)组成。
  3. 标识符名称区分大小写

Python将程序中的任何内容统称为对象,包括数字、字符串与函数

逻辑行与物理行

物理行(Physical Line)是你在编写程序时你所看到的内容
逻辑行(Logical Line)是Python所看到的单个语句

显式行连接

1
2
3
4
5
s='This is a string \
This continues the string.'
print(s)
This is a string This continues the string.

隐式行连接
逻辑行以括号开始,它可以是方括号或花括号,但不能是右括号
可以不使用\

缩进

在逻辑行的开头留下空白区(使用空格或制表符)用以确定各逻辑行的缩进级别
放置在一起的语句必须拥有相同的缩进,每一组这样的语句被称为块(block)

运算符与表达式

运算符

  • +-*/**(乘方)、//(整除)、% (取余)
  • <<(二进制左移) 、>> (二进制右移)
  • &(按位与) 、|(按位或) 、^ (按位异或)、~(按位取反,x的按位取反结果为-(x+1))
    • 转换为二进制
  • <><=>===!=
    • 所有的比较运算符返回的结果均为TrueFalse。请注意这些名称之中的大写字母
  • notandor
    • 短路计算

/除法计算结果是浮点数,即使是两个整数恰好整除,结果也是浮点数
//永远是整数,即使除不尽

1
2
9 / 3 输出3.0
-13 // 3 输出-5

优先级

从最低优先级到最高优先级,同一行的运算符具有相同优先级

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
lambda Lambda表达式
if-else 条件表达式
or 布尔“或”
and 布尔“与”
not x 布尔“非”
in, not in, is, is not, <, <=, >, >=, !=, ==
比较,包括成员资格测试和身份测试
| 按位或
^ 按位异或
& 按位与
<<, >> 移动
+, - 加与减
*, /, //, % 乘、除、整除、取余
+x, -x, ~x 正、负、按位取反
** 求幂
x[index], x[index:index], x(arguments...), x.attribute
下标、切片、调用、属性引用
(expressions...), [expressions...], {key:value...}, {expressions...}
元组、列表、字典、集合

控制流

if语句
条件判断从上向下匹配,当满足条件时执行对应的块内语句,后续的elif和else都不再执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/usr/bin/env python
number=23
guess=int(input('Enter an interger:'))
if guess==number:
print('Congratulations,you guessed it')
print('(but you do not win any prizes!)')
elif guess<number:
print('No,it is a little higher than that')
else:
print('No,it is a little lower than that')
print('Done')

while语句
else语句在循环结束后执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/usr/bin/env python
number=23
running=True
while running:
guess=int(input('Enter an integer:'))
if guess==number:
print('Congratulations,you guessed it')
running=False
elif guess<number:
print('No,it is a little higher than that.')
else:
print('No,it is a little lower than that.')
else:
print('The while loop is over.')
print('Done')

for语句
rang()将会返回一个数字序列,从第一个数字开始,至第二个数字结束。
range(1,5)将输出序列[1,2,3,4]
range(1,5,2)将会输出[1,3]
不会包括第二个数字在内
range()每次只会生成一个数字,list(range(5))返回完整的数字列表

1
2
3
4
5
6
7
8
for i in range(1,5):
print(i)
else:
print('The loop is over')
names=['Michael','Bob','Tracy']
for name in names:
print(name)

else语句在循环结束后执行

break语句
如果中断了一个for或while循环,任何相应循环中的else块都将不会被执行

1
2
3
4
5
6
while True:
s=input('Enter something:')
if s=='quit':
break
print('Length of the string is',len(s))
print('Done')

continue语句

1
2
3
4
5
6
7
8
9
10
while True:
s=input('Enter something')
if s=='quit':
break
if len(s)<3:
print('Too small')
continue
print('Length of the string is',len(s))
print('Done')

1
2
3
4
5
6
n=0
while n<10:
n=n+1
if n%2 ==0:
continue
print(n)

函数

1
2
3
4
def say_hello():
print('hello wolrd')
say_hello()
1
2
3
4
5
6
7
8
9
10
11
def print_max(a,b):
if a>=b:
print(a)
else:
print(b)
print_max(3,4)
x=8
y=10
print_max(x,y)

在定义函数时给定的名称称作“形参”(Parameters)
在调用函数时你所提供给函数的值称作“实参”(Arguments)
函数名其实就是指向一个函数对象的引用,完全可以把函数名赋给一个变量,相当于给这个函数起了一个“别名”

1
2
3
>>> a=abs
>>> a(-1)
1

hex()把一个整数转换成十六进制表示的字符串

局部变量

所有变量的作用域是它们被定义的块,从定义它们的名字的定义点开始

1
2
3
4
5
6
7
8
x=50
def func(x):
print('x is',x)
x=2
print('x is',x)
func(x)
print('x is still',x)

结果是

1
2
3
x is 50
x is 2
x is still 50

当你在一个函数的定义中声明变量时,它们不会以任何方式与身处函数之外但具有相同名称的变量产生关系

全局变量

1
2
3
4
5
6
7
8
9
x=50
def func():
global x
print('x is',x)
x=2
print('x is',x)
func()
print('x is',x)

结果为

1
2
3
x is 50
x is 2
x is 2

默认参数值

默认参数值应该是常数

1
2
3
4
5
def say(message,times=1):
print(message*times)
say('Hello')
say('Hello',2)

关键字参数

1
2
3
4
5
6
def func(a,b=5,c=10):
print('a is {},and b is {} and c is {}'.format(a,b,c))
func(3,7)
func(25,c=24)
func(c=50,a=100)

结果如下:

1
2
3
a is 3,and b is 7 and c is 10
a is 25,and b is 5 and c is 24
a is 100,and b is 5 and c is 50

可变参数

当我们声明一个诸如*param的星号参数时,从此处开始直到结束的所有位置参数都将被收集并汇集成一个称为“param”的元组(Tuple)
类似地,当我们声明一个诸如**param的双星号参数时,从此处开始直至结束的所有关键字参数都将被收集并汇集成一个名为param的字典(Dictionary)

1
2
3
4
5
6
7
8
9
10
11
12
def total(a=5,*numbers,**phonebook):
print('a',a)
#遍历元组中的所有项目
for single_item in numbers:
print('single_item',single_item)
#遍历字典中的所有项目
for first_part,second_part in phonebook.items():
print(first_part,second_part)
print(total(10,1,2,3,jack=1123,John=2231,Inge=1560))

结果如下:

1
2
3
4
5
6
7
8
a 10
single_item 1
single_item 2
single_item 3
jack 1123
John 2231
Inge 1560
None

return语句

从函数中返回,中断函数

1
2
3
4
5
6
7
def maximum(x,y):
if x>y:
return x
elif x<y:
return y
else:
return 'The numbers are equal'

DocStrings 文档字符串

文档字符串约定的格式
一串多行字符串,其中第一行以某一大写字母开始,以句号结束。第二行为空行,后跟的第三行开始是任何详细的解释说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def print_max(x,y):
'''打印两个数值中的最大数。
这两个数都应该是整数
'''
x=int(x)
y=int(y)
if x>y:
print(x,'is maximum')
else:
print(y,'is maximum')
print_max(3,5)
print(print_max.__doc__)

结果如下:

1
2
3
4
5 is maximum
打印两个数值中的最大数。
这两个数都应该是整数

模块

模块用于在别的程序中重用函数

编写模块的方法

  1. 创建一个包含函数与变量,以.py为后缀的文件
  2. 使用撰写Python解释器本身的语言来编写模块(C、Java)

模块分为内置模块(如sys)和自行编写的模块,Python解释器从sys.path所提供的路径中搜索自行编写的模块,所以必须将模块在sys.path内所列出的目录中,比如当前目录

标准库模块,sys模块包含了与Python解释器及其环境相关的功能,也就是所谓的系统功能
运行的脚本名称在sys.argv的列表中是第一个,即sys.argv[0]

1
2
3
4
5
6
7
import sys
print('The command line arguments are:')
for i in sys.argv:
print(i)
print('\n\nThe PYTHONPATH is',sys.path,'\n')

运行:

1
python module_using_sys.py we are arguments

结果:

1
2
3
4
5
6
7
8
The command line arguments are:
module_using_sys.py
we
are
arguments
The PYTHONPATH is ['/home/lee/Documents/pyte', '/home/lee/Documents/pyte/pyte/lib/python36.zip', '/home/lee/Documents/pyte/pyte/lib/python3.6', '/home/lee/Documents/pyte/pyte/lib/python3.6/lib-dynload', '/home/lee/anaconda3/lib/python3.6', '/home/lee/Documents/pyte/pyte/lib/python3.6/site-packages']

.pyc文件

将Python模块转换成中间形式的文件,以提高效率
按字节码编译的(Byte-Compiled)文件,这一文件以.pyc为其扩展名
通常会创建在与对应的.py文件所处的目录中

from…import语句

直接将需要的变量导入程序

1
from sys import argv

尽量避免使用from…import语句,而去使用import语句
避免在你的程序中出现名称冲突

模块的name

每个模块都有一个名称,而模块中的语句可以找到它们所处的模块的名称。
可以用于确定模块是独立运行的还是被导入进来运行
每一个Python模块都定义了它的__name__属性。如果它与__main__属性相同则代表这一模块是由用户独立运行的

1
2
3
4
if __name__ == '__main__':
print('This program is being run by itself')
else:
print('I am being imported from another module')
1
2
3
4
5
6
7
python module_using_name.py
This program is being run by itself
python
>>> import module_using_name
I am being imported from another module
>>>

编写自己的模块

要将模块放在sys.path列出的目录下,或者与其它我们即将导入这一模块的程序相同的目录下

1
2
3
4
5
'''mymodule.py'''
def say_hi():
print('Hi,this is mymodule speaking.')
__version__='0.1'
1
2
3
4
5
'''mymodule_demo.py'''
import mymodule
mymodule.say_hi()
print('Version',mymodule.__version__)
1
2
3
4
5
'''mymodule_demo2.py'''
from mymodule import say_hi,__version__
say_hi()
print('Version',__version__)

mymodule_demo2.py所输出的内容与mymodule_demo.py所输出的内容是一样的

1
2
Hi,this is mymodule speaking.
Version 0.1

dir函数

返回由对象所定义的名称列表
该函数接受参数。如果参数是模块名称,函数将返回这一指定模块的名称列表。如果没有提供参数,函数将返回当前模块的名称列表。

1
2
3
4
5
6
7
8
9
10
11
#给出sys模块中的属性名称
>>>dir(sys)
['__displayhook__', '__doc__', '__excepthook__', '__loader__', '__name__',...
#给出当前模块的属性名称
>>>dir()
['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'module_using_name', 'sys']
>>>a=5
['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'a', ...

包是指一个包含模块与一个特殊的__init__.py文件的文件夹,后者向Python表明这一文件夹是特别的,因为其包含了Python模块

1
2
3
4
5
6
7
8
9
10
11
12
13
<some folder present in the sys.path>/
-world/
-__init__.py
-asia/
-__init__.py
-india/
-__init__.py
-foo.py
-africa/
-__init__.py
-madagascar/
-__init__.py
-bar.py

模块是一种可重用的程序。包是用以组织模块的一种层次结构

数据结构

列表List

列表是可变的,有序的
元素的数据类型可以不同

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
shoplist=['apple','mango','carrot','banana']
len(shoplist)
#最后一个
shoplist[len(shoplist)-1]
shoplist[-1]
# 遍历
for item in shoplist:
print(item,end=' ')
# 增加
shoplist.append('rice')
shoplist.insert(1,'water')
# ['apple', 'water', 'mango', 'carrot', 'banana']
# 更新
>>> shoplist[1]='water'
>>> shoplist
['apple', 'water', 'carrot']
# 删除最后一个
>>> shoplist.pop()
'banana'
>>> shoplist
['apple', 'water', 'mango', 'carrot']
# 删除指定
>>> shoplist.pop(1)
'water'
>>> shoplist
['apple', 'mango', 'carrot']
#排序改变本身
shoplist.sort()
print('Sorted shopping list is',shoplist)
olditem=shoplist[0]
del shoplist[0]
L=['Apple',123,True]
s=['python','java',['asp','php'],'scheme']
>>> L=[]
>>> L
[]
>>> len(L)
0

元组Tuple

有序,不可变

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 空元组
()
# 只有一个元素的元组
(1,)
zoo=('python','elephent','penguin')
len(zoo)
new_zoo='monkey','camel',zoo
# ('monkey', 'camel', ('python', 'elephent', 'penguin'))
new_zoo[2]
new_zoo[2][2]
# 元组中的可变元素
>>> t=('a','b',['A','B'])
>>> t
('a', 'b', ['A', 'B'])
>>> t[2][0]
'A'
>>> t[2][0]='Y'
>>> t
('a', 'b', ['Y', 'B'])

字典Dict

无序
使用键-值(key-value)存储,具有极快的查找速度
在其他语言中称为map

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
ab={
'Swaroop':'swaroop@swaroopch.com',
'Larry':'larry@wall.org',
'Matsumoto':'matz@ruby-lang.org',
'Spammer':'spammer@hotmail.com'
}
# 取值
ab['Swaroop']
# 删除
del ab['Spammer']
ab.pop('Spammer')
len(ab)
for name,address in ab.items():
print('Contact {} at {}'.format(name,address))
# 赋值
ab['Guido']='guido@python.org'
# in判断是否存在
if 'Guido' in ab:
print("\nGuido's address is",ab['Guido'])
# get()判断是否存在,不存在返回None,或指定的value
ab.get('Thomas')
ab.get('Thomas',-1)
# 按key排序
>>> sorted(d.keys())
['Adam', 'Jack', 'Michael', 'Tracy']
>>> sorted(d.keys(),reverse=True)
['Tracy', 'Michael', 'Jack', 'Adam']
# 按value 排序
>>> sorted(d.items(),key=lambda item:item[1])
[('Adam', 67), ('Tracy', 85), ('Jack', 88), ('Michael', 95)]

返回None的时候Python的交互环境不显示结果

和list比较,dict有以下几个特点:

  • 查找和插入的速度极快,不会随着key的增加而变慢;
  • 需要占用大量的内存,内存浪费多。

而list相反:

  • 查找和插入的时间随着元素的增加而增加;
  • 占用空间小,浪费内存很少。

dict的key必须是不可变对象,使用key的Hash值计算value的存储位置

items() 方法将字典的元素转化为了元组,而key参数对应的 lambda 表达式的意思则是选取元组中的第二个元素作为比较参数(如果写作 key=lambda item:item[0] 的话则是选取第一个元素作为比较对象,也就是 key 值作为比较对象。lambda x:yx 表示输出参数,y 表示 lambda 函数的返回值),所以采用这种方法可以对字典的 value 进行排序。注意排序后的返回值是一个 list,而原字典中的名值对被转换为了 list 中的元组。

序列Sequence

序列的三种形态——列表、元组与字符串
资格测试(in、not in)、索引操作、切片
切片操作不包含结束位置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
shoplist=['apple','mango','caroot','banana']
name='swaroop'
shoplist[0] #apple
shoplist[1] #mango
shoplist[2] #caroot
shoplist[3] #banana
shoplist[-1] #banana
shoplist[-2] #caroot
shoplist[1:3] #['mango', 'caroot']
shoplist[2:] #['caroot', 'banana']
shoplist[1:-1] #['mango', 'caroot']
shoplist[:] #['apple', 'mango', 'caroot', 'banana']
shoplist[::1]
# ['apple', 'mango', 'carrot', 'banana']
shoplist[::2]
# ['apple', 'carrot']
shoplist[::3]
# ['apple', 'banana']
shoplist[::-1]
# ['banana', 'carrot', 'mango', 'apple']
name[0] #s
name[1:3] #wa
name[2:] #aroop
name[1:-1] #waroo
name[:] #swaroop

集合Set

无序,不重复
不可以放入可变对象,因为无法保证不重复

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 创建一个set,需要提供一个list作为输入集合
>>> bri=set(['brazil','russia','india'])
>>> 'india' in bri
True
>>> 'usa' in bri
False
>>> bric=bri.copy() #不是同一个
>>> bric.add('china')
>>> bric.issuperset(bri)
True
>>> bric
{'india', 'china', 'russia', 'brazil'}
>>> bri
{'india', 'russia', 'brazil'}
>>> bri.remove('russia')
>>> bri & bric
{'india', 'brazil'}

不可变对象

str是不变对象,而list是可变对象

1
2
3
4
5
6
7
8
9
10
11
12
13
>>> a=['c','b','a']
>>> a
['c', 'b', 'a']
>>> a.sort()
>>> a
['a', 'b', 'c']
>>> a='abc'
>>> b=a.replace('a','A')
>>> b
'Abc'
>>> a
'abc'

replace方法创建了一个新字符串’Abc’并返回
对于不变对象来说,调用对象自身的任意方法,也不会改变该对象自身的内容。相反,这些方法会创建新的对象并返回,这样,就保证了不可变对象本身永远是不可变的

引用

1
2
3
4
5
6
7
8
9
10
11
12
shoplist=['apple','mango','carrot','banana']
#两个变量指向同一个列表
mylist=shoplist
del shoplist[0]
print('shoplist is',shoplist)
print('mylist is',mylist)
#两个变量指向不同的列表
mylist=shoplist[:]
del mylist[0]
print('shoplist is',shoplist)
print('mylist is',mylist)

字符串

1
2
3
4
5
6
7
8
9
name = 'Swaroop'
name.startswith('Swa')
'a' in name
name.find('war') != -1
delimiter = '_*_'
mylist = ['Brazil', 'Russia', 'India', 'China']
print(delimiter.join(mylist))
# Brazil_*_Russia_*_India_*_China

解决问题

单独开一章

面向对象编程

类与对象是面向对象编程的两个主要方面。一个类(Class)能够创建一种新的类型(Type),其中对象(Object)就是类的实例(Instance)

字段(Field)
方法(Method)
字段与方法通称类的属性(Attribute)
实例变量(Instance Variables)
类变量(Class Variables)

1
2
3
4
5
6
class Person:
def say_hi(self):
print('Hello, how are you?')
p = Person()
p.say_hi()

init方法

__init__方法会在类的对象被实例化(Instantiated)时立即运行,用于初始化

1
2
3
4
5
6
7
8
9
class Person:
def __init__(self, name):
self.name = name
def say_hi(self):
print('Hello, my name is', self.name)
p = Person('Swaroop')
p.say_hi()

类变量和对象变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
class Robot:
"""表示有一个带有名字的机器人。"""
# 一个类变量,用来计数机器人的数量
population = 0
def __init__(self, name):
"""初始化数据"""
self.name = name
print("(Initializing {})".format(self.name))
# 当有人被创建时,机器人
# 将会增加人口数量
Robot.population += 1
def die(self):
"""我挂了。"""
print("{} is being destroyed!".format(self.name))
Robot.population -= 1
if Robot.population == 0:
print("{} was the last one.".format(self.name))
else:
print("There are still {:d} robots working.".format(
Robot.population))
def say_hi(self):
"""来自机器人的诚挚问候
没问题,你做得到。"""
print("Greetings, my masters call me {}.".format(self.name))
@classmethod
def how_many(cls):
"""打印出当前的人口数量"""
print("We have {:d} robots.".format(cls.population))
droid1 = Robot("R2-D2")
droid1.say_hi()
Robot.how_many()
droid2 = Robot("C-3PO")
droid2.say_hi()
Robot.how_many()

population是类变量,Robot.populationself.__class__.population,共享数据
name是对象变量,self.name

how_many是类方法

Robot.__doc__ 访问类的文档字符串
Robot.say_hi.__doc__访问方法的文档字符串

__privatevar私有变量

继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
class SchoolMember:
def __init__(self,name,age):
self.name=name
self.age=age
print('Initialized SchoolMember:{}'.format(self.name))
def tell(self):
print('Name:"{}" Age:"{}"'.format(self.name,self.age),end=" ")
class Teacher(SchoolMember):
def __init__(self,name,age,salary):
SchoolMember.__init__(self,name,age)
self.salary=salary
print('Initialized Teacher:{}'.format(self.name))
def tell(self):
SchoolMember.tell(self)
print('Salary: "{:d}"'.format(self.salary))
class Student(SchoolMember):
def __init__(self,name,age,marks):
SchoolMember.__init__(self,name,age)
self.marks=marks
print('Initialized Student:{}'.format(self.name))
def tell(self):
SchoolMember.tell(self)
print('Marks:"{:d}"'.format(self.marks))
t=Teacher('Mrs. Shrividya',40,30000)
s=Student('Swaroop',25,75)
print()
members=[t,s]
for member in members:
member.tell()

SchoolMember.__init__(self,name,age)调用父类的构造方法
SchoolMember.tell(self)调用父类的方法
多重继承

输入与输出

1
2
3
4
5
6
7
8
9
10
11
def reverse(text):
return text[::-1]
def is_palindrome(text):
return text==reverse(text)
something=input('Enter text:')
if is_palindrome(something):
print('Yes,it is a palindrome')
else:
print('No,it is not a palindrome')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
poem='''\
Programming is fun
When the work is done
if you wanna make your work also fun:
use Python!
'''
f=open('poem.txt','w')
f.write(poem)
f.close()
f=open('poem.txt')
while True:
line=f.readline()
if len(line)==0:
break
print(line,end='')
f.close()

阅读模式(’r’)
写入模式(’w’)
追加模式(’a’)
文本模式(’t’)
二进制模式(’b’)
在默认情况下,open() 会将文件视作文本(text)文件,并以阅读(read)模式打开它。

readline会读取换行符

Pickle

将任何纯 Python 对象存储到一个文件中,并在稍后将其取回。这叫作持久化(Persistently)存储对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import pickle
shoplistfile='shoplist.data'
shoplist=['apple','mango','carrot']
f=open(shoplistfile,'wb')
pickle.dump(shoplist,f)
f.close()
del shoplist
f=open(shoplistfile,'rb')
storedlist=pickle.load(f)
print(storedlist)

Unicode

1
# encoding=utf-8

使用 io.open 并提供了“编码(Encoding)”与“解码(Decoding)”参数来告诉 Python 我们正在使用 Unicode。

异常

错误处理器:抛出错误,打印出检测到的错误发生的位置

EOFError,文件结尾错误(End of File)

处理异常

1
2
3
4
5
6
7
8
try:
text=input('Enter something-->')
except EOFError:
print('Why not you do an EOF on me?')
except KeyboardInterrupt:
print('You cancelled the operation.')
else:
print('You entered {}'.format(text))
1
2
3
4
5
6
7
8
9
10
11
# Press ctrl + d
$ python exceptions_handle.py
Enter something --> Why did you do an EOF on me?
# Press ctrl + c
$ python exceptions_handle.py
Enter something --> ^CYou cancelled the operation.
$ python exceptions_handle.py
Enter something --> No exceptions
You entered No exceptions

else 子句将在没有发生异常的时候执行

抛出异常

raise 语句可以引发一次异常,具体方法是提供错误名或异常名以及要抛出(Thrown)异常的对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class ShortInputException(Exception):
def __init__(self,length,atleast):
Exception.__init__(self)
self.length=length
self.atleast=atleast
try:
text=input('Enter somethin--->')
if len(text)<3:
raise ShortInputException(len(text),3)
except EOFError:
print('Why did you do an EOF on me?')
except ShortInputException as ex:
print(('ShortInputException:The input was '+'{0} long,expected at least {1}').format(ex.length,ex.atleast))
else:
print('No exception was raised.')

Try…Finally

无论是否会发生异常必然执行,finally

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import sys
import time
f=None
try:
f=open("poem.txt")
while True:
line=f.readline()
if len(line)==0:
break
print(line,end='')
sys.stdout.flush()
print('Print ctrl-c now')
time.sleep(2)
except IOError:
print('Could not find file poem.txt')
except KeyboardInterrupt:
print('!! You cancelled the reading from the file.')
finally:
if f:
f.close()
print('(Cleaning up:Closed the file)')

with语句

使用with open语句会自动关闭文件

1
2
3
with open('poem.txt') as f:
for line in f:
print(line,end='')

标准库

sys模块
日志模块logging

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import os
import platform
import logging
if platform.platform().startswith('Windows'):
logging_file=os.path.join(os.getenv('HOMEDRIVE'),os.getenv('HOMEPATH'),'test.log')
else:
logging_file=os.path.join(os.getenv('HOME'),'test.log')
print('Logging to',logging_file)
logging.basicConfig(
level=logging.DEBUG,
format='%(asctime)s:%(levelname)s:%(message)s',
filename=logging_file,
filemode='w',
)
logging.debug('Start of the program')
logging.info('Doing something')
logging.warning('Dying now')

更多

Lambda

1
2
3
4
points=[{'x':2,'y':3},{'x':4,'y':1}]
points.sort(key=lambda i:i['y'])
print(points)

列表推导

1
2
3
listone=[2,3,4]
listtwo=[2*i for i in listone if i>2]
print(listtwo)