一 写在前面
未经允许,不得转载,谢谢~~
接触Python应该有一年多的时间了,凭借着C++的经验也没有认真地系统地学习过Python就直接上手了~
目前用的还算可以,但总觉得不够,都说磨刀不误砍材工,感觉还是很有必要重新系统地学习一下。
本文主要参考书本:Magnus Lie Hetland著,司维等人译的Python基础教程。在这里做个主要的笔记记录,并不会包含所有的知识点哦,像python的安装,加减法这样的就不写上来浪费大家的时间了,当然太细节的东西也只需要用到的时候再去学就可以了。
chap 1 基础知识
1.1 基础数字和表达式
- 算数表达
- 除法:
/
- 整除:
//
- 取余:
%
- 变量
- python的变量非常的灵活;
- 变量名可以包括字母、数字和下划线,但是不能以数字开头;
- 函数
- 常用内建函数例如:
abs()
pow()
round()
- 模块
- 直接导入模块
import model
,然后使用model.function
调用函数 - 直接导入模块中的函数
from model import function
1.2 字符串
- 字符串表示
-
str()
: 把值转换成合理形式的字符串 -
repr()
:以合法的python表达式的形式来表示值;
- 数据输入
-
input()
: 假设用户输入的是合法的python表达式; -
raw_input()
:所有的输入当成原始输入;
- 长字符串表示
- 用三个引号
'''
代替普通引号; - 或者一行中的最后一个字符是反斜线
\
- 原始字符串
- 就是其中的转义字符不起作用,该是什么样,就是什么样;
- 原始字符串以
r
开头;
chap2 列表和元祖
- 两者的主要区别在于列表可以修改,而元祖不能;
- 序列本身也可以包含其他的序列;
2.1 通用序列操作
- 所有的序列都包含索引、分片、加、乘、检查元素是否存在等操作。
- 除此,python还具有计算序列长度、找出最大最小元素的内建函数。
- 索引
- 字符串就是由字符组成的序列,以此为例:
greeting='Hello'
- 索引值从第一个数0开始,
greeting[0]='H'
- 负数索引,从最后一个数-1开始,
greeting[-1]='o'
- 分片
- 用于访问一定范围内的元素;
- 通过
:
相隔的两个索引来实现; numbers=[0,1,2,3,4,5,6,7]
numbers[3:6]=[3,4,5]
- 第一个索引值包括在边界内,第二个索引值不包括在边界内;;
- 例:访问最后3个元素
numbers[-3:-1]
或者直接numbers[-3:]
,将最后一个置空。 - 以上的步长都是默认设置为1的;
- 显示指定步长:
numbers[1:6:2]
从第1个(包括)到第6个(不包括)中每2个元素的第一个; - 显示指定负步长:
numbers[6:1:-2]
从第6个(包括)到第1个(不包括)每2个元素的第一个;
- 序列相加
-
+
可以直接将序列相加; - 但是必须是同个类型的数据;
- 乘法
'hello'*3=‘hellohellohello’
[21]*3=[21,21,21]
- 可以用来初始化空列表:
sequence=[None]*10
- 成员资格
- 检查元素是否在内
in
- 在则返回
True
- 不在则返回
False
- 长度、最大值和最小值
- python的内建函数
-
len()
序列中所含元素数量; -
min()
序列中最小值; -
max()
序列中最大值;
2.2 列表:python的‘苦力’
- 列表不同于元祖和字符串的地方:列表是可变的。
- list函数
-
list()
可以根据字符串创建列表; - 例:
list['hello']=['h','e','l','l','o']
; - list适用于所有类型的序列,不只是字符串;
- 基本的列表操作
- 所有序列的标准操作:索引、分片、加、乘、长度等列表都适用;
- 一些可以改变列表的方法:元素赋值、元素删除、分片赋值、列表方法;
- 元素赋值:
x[1]=2
- 删除赋值:
del x[1]
- 分片赋值:
x[2:]=list('hello')
- 列表方法:方法是与某些对象有紧密联系的函数,调用方式:
对象.方法()
-
.append()
在列表末未追加元素; -
.count()
统计某个元素出现的次数; -
.extend()
可以用新列表扩展原有列表; -
.index()
找出列表中某个值第一个匹配项的索引位置; -
.insert()
将对象插入到列表中; -
.pop()
移除列表中的一个元素(默认是最后一个),并返回元素值; - 结合使用
.append()
和.pop()
就可以实现栈。 -
.remove()
移除列表中某个值的第一个匹配项。 -
.reserve()
将列表中的元素反向存放。 -
.sort()
在原来的位置上对列表进行排序,默认从小到大。如果需要保留原来的x,需要用y=x[:]
深度复制x的值,然后对y排序。注意y=x
是没有用的,是浅复制。
2.3 元祖:不可变序列
- 如果用逗号分隔了一些值,就自动创建了元祖。
1,2,3=(1,2,3)
- 元祖是通过圆括号括起来的。
- 空元祖:
()
- 只有一个值的元祖:
42,=(42,)
必须有逗号
- tuple函数
- 与列表的list函数基本一致。
- 把序列做为参数并将其转换为元祖
tuple([1,2,3])=(1,2,3)
- 基本元祖操作
- 创建元祖:
x=1,2,3
- 访问元祖:
x[1]
- 可否替代
- 一般来说,大多事sequence都由list满足;
- 但是元祖可以在映射中当成键来使用,但列表不行;
- 元祖作为很多内建函数和方法的返回值存在,这些时候就必须对元祖进行处理。
chap3 使用字符串
3.1 基本字符串操作
- 所有序列的标准操作:索引、分片、加、乘、长度、取最大最小等对字符串都适用;
- 但是字符串是不可变的。
3.2 字符串格式化
-
%s
格式化成字符串 -
%f
格式化成浮点数 -
%.3f
格式化成浮点数,并保留3位小数 -
%C
格式化成单字符 -
%i
格式化成带符号的十进制整数
3.3 字符串方法
.find()
- 在一个较长的字符串中查找子字符串,返回子串所在位置的最左端索引;
- 若没有则返回-1;
- 方法还可以指定起始和终止值所在的范围;
join()
- 是
split()
的逆方法; - 队列元素必须是字符串;
- 例:
seq=['1','2','3']
sep='+'
sep.join(seq)
# seq='1+2+3'
lower()
- 返回字符串的小写字母版;
replace()
- 返回某字符串的匹配项军备替换后得到的字符串;
.replace('等待替换','最新替换')
split()
-
join()
的逆方法,用来将字符串分割成序列; -
.split('\')
分割以\
为界限的字符。
strip()
- 返回去除两侧(不包括内部)空格的字符串
- 也可以去除两端指定的字符,
.stripe('两端待去除的')
每天更新一点点~~~~
chap4 字典
- 通过名字引用值的数据结构;
- 字典是python中唯一内建的映射类型;
- 字典中的值没有特殊的顺序,但是都存储在一个特定的键key中;
- 键可以是数字、字符串甚至是元祖;
4.1 创建和使用字典
phonebook={'alice':'2341', 'beh':'9021'}
- 字典由多个键与其对应的值所构成的对组成
- 每个键和对应的值用
:
隔开 - 向之间用
,
隔开 - 字典由一组
{}
括起来。 - 空字典:
{}
- 字典的键是唯一的,但是其值并不唯一。
4.2 dict函数
- 可以将其他的映射(比如其他字典),或者(键,值)这样的序列对建立字典。
- 例:
items=[('name','alice'),('age',12)]
d=dict(items)
print(d['name'])
# 'alice'
4.3 基本字典操作
很多行为都与序列类似。
-
len(d)
返回键值对数量; -
d[k]
返回键值为k的值; -
d[k]=v
给d[k]赋值; -
del d[k]
删除键为k的项; -
k in d
检查是否有键值为k的项;
4.4 字典方法
-
.clear()
清除字典中所有的项,且为原地操作,in-place operation; -
.copy()
是一个浅复制,可以使用copy的deepcopy()
函数完成深复制; -
.fromkeys()
使用给定的键建立新的字典,每个键默认对应的值为none; -
.get()
当用这个方法访问不存在的键值时也不会报错,而是会得到None值; -
.items()
将所有的字典用列表方式返回,列表项中每一个项都来自(键,值); -
.iteritems()
返回一个迭代器对象而不是列表; -
.keys()
和.iterkeys()
分别将字典中的键以列表方式返回,和返回针对键的迭代器; -
.values()
和.itervalues()
分别将字典中的值以列表方式返回,和返回针对值的迭代器; -
.pop()
获取对应于给定键的值,然后将键-值对从字典中移除; -
.popitem()
弹出随机的项; -
.update()
可以利用一个字典项更新另一个字典;
chap5 条件、循环和其他语句
5.1 print和import的更多信息
- 在用print的时候用
,
可以输出多个表达式 - import的时候可以导入整个模块,模块中的一个或多个函数,也可以用
as
关键字起别名;
5.2 赋值的多种用法
- 序列解包
- 多个赋值操作可以同时进行:
x,y,x=1,2,3
- 可以用来交换两个或更多变量:
x,y=y,x
- 当函数或者方法返回元祖时,这个特性就会特别有用;
- 链式赋值
- 链式赋值是将同一个值赋值赋给多个变量的捷径;
x=y=sonfunctions()
- 增量赋值
- 将
x=x+1
写成x+=1
5.3 语句块:缩排的乐趣
- python没有像C++这样的{}来表示语句块
- 都用缩进来表示语句块
5.4 条件和条件语句
- 真假判断
- 以下值都为假:
False
None
0
""
()
[]
{}
- 除了以上都为真。
- 条件执行和if语句
if
elif
else
- if语句里面可以嵌套if语句
- 更复杂的条件
-
x==y
x等于y -
x<y
x>y
x<=y
x>=y
-
x!=y
x不等于y -
x is y
x和y是一个对象 -
x is not y
x和y不是一个对象 -
x in y
x是y的成员 -
x not in y
x不是y的成员 - 字符串按照字母顺序排列进行比较
-
and
条件同时成立 -
or
有一个条件成立
- 断言
-
assert
语句在程序中置入检查点,如果错误就中断程序并给出提示;
5.5 循环
- 常用语句
while
for
- 能使用for就尽量不用while
- 一些迭代工具: zip并行迭代
-
zip
可以用于并行迭代,把两个序列压缩在一起,然后返回一个元祖的列表; - 也可以用于多个序列
- 另外可以用于不等长的序列,最短的用完以后就停止
- 例:
names=['alice','ivy']
ages=['12','18']
zip(names,ages)
for name, age in zip(names,ages):
print(name,age)
- 一些迭代工具: enumerate编号迭代
- 想要迭代序列中的对象,同时还要获取当前对象的索引值时;
- 例:
for index,string in enumerate(strings):
if `xxx` in string:
strings[index]='new'
- 一些迭代工具: 翻转和排序迭代
-
reversed
和sorted
返回翻转或者排序后的版本;
- 跳出循环
-
break
跳出(结束)循环; -
continue
跳出剩余循环体但是不结束循环; - 用
while
方式根据想要的条件结束循环;
5.6 列表推导式
- 列表推导式list comprehension是利用其它的列表创建新的列表
- 例:
[x*x for x in range(10)]
- 例:
[x*x for x in range(10) if x % 3==0]
- 例:
[(x,y) for x in range(3) for y in range(3)]
- 一定是使用
[]
方括号
5.7 补充
-
pass
什么都不做,通常用于占位 -
del
我们也可以使用del
删除某个变量,但只是删除变量名本身,并不删除实际的值, python解释器会直接做垃圾回收。 -
exec
和eval
都不是很常用;
chap 6 抽象:函数
- 即如何将语句组织成函数;
6.1 创建函数
-
def functionname(params)
创建名为functionname的函数 - 给函数增加备注,除了用
#
之外,还可以在函数内部用''
两个单引号里面写入对函数的说明,这样会作为函数的一部分进行存储,称为文档字符串。 - 调用
functionname.__doc__
就可以访问到该函数对应的文档字符串;
6.2 函数参数
- 普通参数的用法就是按照顺序给定
- 或者直接用关键字给定参数,这样就可以不用管参数顺序
-
*params
可以将所有的值放置同一个元祖中,将这些值收集起来,然后使用。 -
*
的意思就是收集其余的位置参数,如果不提供任何供收集的参数,params就是一个空元祖()
-
**parmas
做的事情就是能处理关键字参数的收集工作,将关键字-值作为项收集成字典。 - 具体可以参考博客:Python 中函数的 收集参数 机制
chap 7 更加抽象:类
- 面向对象三大特性:多态、封装、继承
- 创建一个新的类:
class className:
, 然后在里面用def
关键字定义函数; -
self
关键字值得是对象自身的引用,这点在类中非常有用; -
self
事实上是方法和函数的区别
chap8 异常
- python用异常对象来表示异常情况。遇到错误后,会引发异常;
- 如果异常对象未被处理或者抓捕,程序就会用所谓的回溯(traceback)终止执行;
8.1 一些内建异常
-
Exception
: 所有异常的基类 -
AttributeError
: 特性引用或赋值失败时引发 -
IOError
: 试图打开不存在的文件时 -
IndexError
: 使用序列中不存在的索引时 -
KeyError
: 使用映射中不存在的键时 -
NameError
:在找不到名字(变量)时 -
SyntaxError
: 在代码为错误形式时; -
TypeError
: 在内建操作或者函数应用于错误类型的对象时 -
ValueError
: 在内建操作或者函数应用于正确类型的对象,但是该对象使用不合适的值时 -
ZeroDivisionError
: 在除法或者模除操作的第二个参数为0时引发
8.2 自定义异常类
- 绝大多数以上的情况已经够用了;
- 但需要自定义时,只需要自己继承
Exception
类即可; class SomeCustomException(Exception):pass
8.3 捕捉异常
- 用
try/except
关键字来捕捉异常并作出一些处理 -
try:
后面跟需要检查异常的语句 -
except Exception:
后面跟具体想要捕捉的异常类型,以及对应的错误处理 - 可以有多个
except
- 可以再try/except语句后面加个
else:
子句 - 还有一个
finally:
关键字用于在可能的异常后进行处理 - 例:
try:
1/0
except NameError:
print ("unknow variable")
else:
print ("that went well")
finally:
print ("cleaning up")
8.4 异常与函数
- 异常在函数内引发而不被处理,就会传播到函数调用的地方;
- 如果在调用地方也没有被处理,就会继续传播到主程序;
- 如果主程序还是没有处理,那么会跟着堆栈跟踪终止;
- 当然某些程序中使用
if/else
实现异常的处理会比try/except
更好;
chap9 方法、属性和迭代器
9.1 构造方法
__init__()
- 当一个对象被创建后,会立即调用构造方法;
- 想给构造方法传递参数的时候,就直接在初始化类的时候把参数传进去就好了;
- 重写一般方法和特殊的构造方法
- 当一个类(子类)继承一个类(母类、超类)时可以重写其中的方法;
- 首先会在子类中查找方法
- 找不到的时候会再去母类中查找
- 但是子类默认情况下是没有初始化母类的构造方法,那么可以用一下2、3点来解决;
- 调用未绑定的母类构造方法
- 简单来说,就是在子类的初始构造函数中增加一行
母类.__init__(self)
- 使用super函数
- 在子类的构造初始函数中增加一行
super(母类,self).__init__()
9.2 成员访问
- 基本的序列和映射规则
- 序列和映射是对象的集合。
- 如果对象不可变,那么使用前2个方法;
- 如果对象可变的,那么使用4个方法;
-
__len__(self):
这个方法应该返回集合中所含项目的数量; -
__getitem__(self, key):
这个方法返回与所给键对应的值; -
__setitem__(self,key,value):
这个方法应该按照一定的方式存储和key相关的value,该值随后可以用__getitem__
方法来获取。当然,也能为可以修改的对象定义这个方法; -
__delitem__(self,key)
:这个方法在对一部分对象使用del语句时被调用,同时必须删除和元素相关的键。这个方法也是为可以修改的对象定义的;
- 子类化列表、字典和字符串
- 实现以上所有需要的方法是一项繁重的工作,并且很难做好。
- 如果只想在一个操作中自定义行为,而其他的方法不用实现:继承
- 就是当想要子类化一个内建类型(例list),就去继承list类,然后重写自己想要的方法即可。
9.3 属性
- property函数
- 它能够实现将方法封装成属性;
- 具体的可以参考:对于Python中@property的理解和使用
- 静态方法和类成员方法
- 静态方法和类成员方法分别在创建时被装入Staticmethod类型和Classmethod类型的对象中。
- 静态方法的定义没有self参数,且可以被类本身调用;
- 类成员方法在定义时需要名为cls的类似于self的参数,类成员方法可以用来直接用类的具体对象调用。
- 也可以用
@
在方法或者函数的上方将装饰器列出,例:@staticmethod
@classmethod
9.4 迭代器
- 方法
__iter__
迭代器规则的基础
- 迭代器规则
-
__iter__
方法返回一个迭代器 - 迭代器指的就是具有
next
方法的对象; - 在调用
next
方法时,迭代器会返回他的下一个值。 - 在python0.3中,为
__next__
方法
- 从迭代器得到序列
- 例:
class TestIterator:
value=0
def __next__(self):
self.value+=1
if self.value > 10 : raise StopIteration
return self.value
def __iter__(self):
return self
ti=TestIterator()
list(ti)
# [1,2,3,4,5,6,7,8,9,10]
-
__iter__
函数返回自身 -
__next__(self)
中放入你希望他迭代做的事情
9.5 生成器
- 生成器和迭代器是可能是近几年来引入的最强大的两个特性;
- 生成器可以帮助读者写出非常优雅的代码;
- 生成器是一种用普通的函数语法定义的迭代器;
- 创建生成器
- 创建一个生成器就像创建函数一样简单;
- 例如要把
nested=[[1,2],[3,4],[5]]
按顺序打印出来,解决的方法如下:
def flatten(nested):
for sublist in nested:
for element in sublist:
yield element
- 任何包含
yield
语句的函数称为生成器; - 生成器的行为和普通函数有很大的差别。它不是像return那样返回值,而是每次产生多个值。每次用yield语句产生一个值,函数就会被冻结;即函数停在那里等待被激活,函数被激活后就从停止的那个点开始执行。
- 接下来就可以通过在生成器上迭代来使用所有的值;
for num in flatten(nested):
print num
# or
list(flatten(nested))
- 更多
- 有需要使用的话推荐看这里吧:Python的生成器
暂时先更到这里啦~~~~~~~
希望大家能一起学习嘻嘻
网友评论
+ `元祖`=>`元组`
另外需要注意的是,《Python基础教程 第二版》里面保留了很多Python2的内容。比如,`raw_input()`函数在Python3里面不再适用,调用基类构造函数可以有更简单的方法(少打__几个__字母)。
3天看完一本书,膜拜ing
没有看完,看到第10章就不想看了啊哈哈哈