Python 基础教程(第二版)
第一章
- 在 Python 3 中可直接使用长整数,而不必添加 L 或者 l 的后缀。
- print在 Python 3 中是函数。
- 在交互式解释器中使用 if 语句,需要两次回车。
- 书中的例子 math.floor(32.9) 的结果是32.0 , 在 Python 3 中结果是32
- 可以使用变量来引用函数,例如 foo = math.sqrt, foo(4) 的结果就是2.0
- nan abbr. Not a Number
- Python 本身提供了对复数 ( Complex Number ) 的支持,需要导入 cmath 模块。
- 值被转换成字符串的两种机制
- str函数:把值转换成合理的形式,便于用户理解
- repr函数:创建一个字符串并以合法的 Python 格式显示字符串。可以用反引号` `来实现 。
- input 和 raw_input 的比较
- 列表内容
- 长字符串:使用三个引号可跨越多行来表达字符串
普通字符串也可跨行,在一行末尾加 \ 使换行符转义即可 - 原始字符串:以 r 开头,不会把反斜线看做特殊字符,输入的每个字符都会与书写字符保持一致。不能再原始字符串地结尾输入反斜线。
- Unicode字符串:以 u 开头。Python 中普通字符串是以8位的ASCII码形成储存的,而Unicode字符串则是以16位储存的。在 Python 3中所有字符串都是Unicode字符串。
- ord()函数获取字符的整数表示,chr()函数将对应的编码表示成字符
- python对bytes类型的数据用b前缀的单引号或者双引号表示,用Unicode表示的str通过encode()方法可以编码为制定的bytes。反之,将bytes编程str就要使用decode()方法,其中传入errors=’ignore’忽略错误字节。
第二章
- 分片中,只要左边的索引比它右边的晚出现在序列中,得到的就会是空序列。置空最后一个索引,即可得到序列结尾的元素,这样的方法同样适用于开头。
- 步长( Step Length )
- 在分片中,步长隐式设置为 1 , 步长不能为 0,为负时时从右到左 提取元素 (从末尾到开始,而不是从第一个索引到第二个索引), 此时,前两个索引也应该是前大后小 。
- 用一个数字 x 乘以一个序列,会得到原序列重复 x 次的新序列。
- 地板除:不管 // 的操作数是什么类型,总会舍去商小数部分。
- list(): 可以根据字符串创建并返回一个列表对象。
- 分片赋值:可以使用和原序列不等长的序列将原序列替换。也可用于插入或删除元素。
- 列表方法:
- append : 在列表末尾增加新的对象
- count :统计某个元素在列表中出现的次数
- extend : 在列表末尾一次性追加另一个列表的多个值
- index : 从列表中找出某个值第一个匹配项的索引的位置
- insert:将对象插入到列表中
- pop : 一处列表中的元素( 默认是最后一个 ),并返回其值
- remove:移出列表中某个值的第一个匹配项,无返回值
- reverse : 将列表中的值反向存储
- sort:在原位置对列表进行排序,无返回值
- sorted():可用于任何序列排序,但总会返回一个列表
- 元组:()表示空元组,若创建只含有一个元素的元组,唯一元素后面要加上 ,
- tuple():与list() 函数相似,将一个序列作为参数并转化成元组,若参数就是元组,返回原元组。
- 在使用print打印用逗号连接的多个字符串时,每个逗号会打印成一个空格。
第三章
- 格式化字符串中 %s 称为转换说明符(conversion specifier),若要在格式化字符串中包括%,则需要使用%%。
- 使用 * 作为字段宽度或者精度,此数值会从元组中读取
- 在字段宽度和精确值之前可以防止一个“标表”, 可以使零,加号,减号或者空格。零表示将会用0占位,减号用来左对齐,空白(“”)用来在整数前面加上空格,这在对其正负数的使用非常有用,例如(‘% 5d’)。最后是加号,表示不管是正数(+1)或是负数(-1)都表示出前面的符号。
- find() : 在一个较长的字符串中查找子字符串,返回子串所在位置的最左端索引,若没有找到返回-1。还接受可选的起始点和结束点参数 , 由起始值和结束值指定的范围包括第一个索引,但不包括第二个索引。
- join() : 用来在字符串中添加元素
- lower() : 返回字符串的小写版
- title() : 将字符串所有单词的首字母大写,即转换为标题
- replace() : 返回某字符串所有匹配项均被替换后得到的字符串
- split() : join() 的逆方法,将字符串分割为序列 , 若不提供任何分隔符,程序会把空格作为分隔符
- strip() : 返回去除两侧( 不包括中间 )空格的字符串 , 也可以去除指定的字符,将他们列为参数即可
- translate() : 类似replace(), 但只能替换单个字符,可以同时进行多个替换 。translate() 需要两个参数,第一个参数是转换表,第二个参数用来制定要删除的字符。
- maketrans():接受两个等长的字符串作为参数,表示第一个字符串中的每一个字符都用第二个字符串中相同位置的字符进行替换。
第四章
- dict() : 通过其他映射(比如字典)或者(键,值)这样的序列对建立字典,或者通过关键字参数来建立字典。如果不带任何参数,则返回一个空字典。
- 字典的格式化字符串:在每个转换说明符中的%字符的后面,减伤用圆括号括起来的键,后面再跟上其他说明元素。
- 字典方法
- clear():清除字典中的所有项,无返回值,或返回值为None。
- copy():返回一个具有相同键值对的新字典,实现的是浅复制(shallow copy),在副本中替换值的时候,原始字典不受影响,而修改某个值的时候,原始的字典也会改变。避免这一问题的一种方法就是深复制(deep copy),复制其包含的所有值。可使用copy模块中的deepcopy函数来实现。
- fromkeys():使用给定的键建立新的词典,每一个键默认对应的值为None,也可以自己提供默认值。例,{}.fromkeys([‘name’, ‘age’], ‘(ubknown)’)。
- get():是更宽松访问字典项的方法,当你试图访问不存在的项的时候,一般方法会出错,而get反复问一个不存在的键是,没有任何异常,而是得到了None值,也可以自己制定“默认值”。例,d.get(‘name’, ‘N/A’)
- has_key() : Python 3 中不包含这个函数。
- items():将所有字典项以列表的形式返回,返回时这些项没有特殊的顺序。在 Python 3.5 中输出列表会在 dict_items() 的括号中
iteritems():作用大致相同,但会返回一个迭代器对象。在 Python 3.5 中已无此函数,换而是__iter__()函数,返回的是列表键的迭代器(dict_keyiterator object)。 - keys() : 将字典中的键以列表的形式返回。iterkeys() 则是返回针对键的迭代器,Python 3.5 中已无此函数,功能与__iter()__相同。
- pop() : 用来获得给定键的值,并将键值对从字典中删除。
- popitem() : 弹出随机项,因为字典中没有顺序的概念。
- setdefault() : 除了获得与键相关联的值外,还可以在不含有给定键的情况下设置相关的值。当键不存在时,setdefault返回默认值(可选)并更新字典;当键存在时,setdefault返回存在值不更新字典。
- update() : 用一个字典更新另一个字典。提供的字典项将会被添加到旧的字典里,若有相同的键则会被覆盖。
- values() : 以列表的形式返回字典中的值,在 Python 3.5 中输出列表会在 dict_items() 的括号中 。在 Python 3.5 中已无itervalues() 函数。
第五章
- print() 可一次打印多个表达式,只需将表达式用 逗号 隔开。如果在结尾出处加上逗号,接下来的语句会与前一条语句在同一行打印(只在脚本中有作用)。
在 Python 3.0 中有一个解包的性质,使用 * 号, 如 a, b, rest* = [1, 2, 3, 4],在a和b被赋值之后,rest就成为了一个包含剩下值的列表。 - 链式赋值(chained assignment):将一个值付给多个变量的捷径
- 增量赋值(augmented assignment): *=, -+, /=, +=
- False , 0 , None , “” , () , [] , {} 这些值在作为布尔表达式的时候,被解释器看作假。但他们互相是不可以用 == 进行判断的。
- endswith() 方法用于判断字符串是否以制定后缀结尾。是,返回 True , 否则返回 False 。
- is : 同一性运算符,用于判断两者是否相同(是否为同一对象),例如,不同列表中相同的两值 x, y, x is y 的结果是 False.
- 字符串可以按照字母顺序排列次序比较,序列也可以同样的方式比较,如果一个序列中包含其他序列元素,比较仍适用于序列元素。
- 布尔运算符:and, or,not。遵循断路逻辑(short-circuit logic)或惰性求值 ( lazy evaluation )
- 内置的条件表达式:a if b else c , 如果 b 是真,返回 a,否则返回 c 。
- assert : 断言,断言后的条件为假,程序崩溃退出,后可再加字符串解释断言。
- xrange() : 返回一个迭代器,和range返回一个列表不同的是,xrange每次只返回一个数,在迭代数量很大的时候,xrange的性能更好。
- 一些迭代工具:
- 并行迭代:程序可同时迭代两个序列 。可以使用 for 循环进行迭代,或者内建的 zip 函数进行并行迭代,将两个序列“压缩”,然后返回一个元组的列表。zip 适用任意长的序列,关键是不等长的序列,在较短的序列结束后就会停止 。
- 编号迭代:想要迭代序列中的对象,同时还要获得当前对象的索引。可以使用 enumerate() 函数,在提供索引的地方迭代索引-值对。
- 翻转和排序迭代: reversed 和 sorted 函数,类似列表的 reverse 和 sort 方法,但作用于任何序列或者可迭代对象上,并且返回翻转或排序后的版本。但是 sorted 返回列表,而 reversed 返回迭代器。
- 列表推导式( list comprehension ):利用其它列创建新的列表
- pass:让程序什么也不做,起到占位符的作用。
- del : 不仅会移除一个对象的引用,还会移除那个名字本身。
- exec:执行一个字符串的函数,例如,exec
- eval:用于求值,是类似exec的内置函数,eval 用于计算表达式的值
- ord():返回单字符字符串的 int 值
第六章
- callable():用于判断函数是否可调用。在 Python 3.0 中不再可用,使用 hasattr() 代替。
- 文档字符串:如果在函数开头下面字符串,它就会作为函数的一部分进行存储。可用 functionname.__doc__ 的方式进行访问。
- 内建的 help() 函数非常有用,可在交互式解释器中使用,可以得到关于函数包括文档字符串的信息。
- 位置参数和关键字参数可以联合使用,但要把位置参数放在前面。
- 收集参数:在形参前加上 * 可以将所有参数放在一个元组中, 联合使用 进行关键字参数收集则会返回字典而不是元组。如果参数本来是元组或者字典,那么使用 * 或 ** 就会达到翻转效果。
- 作用域( 命名空间 ) : 除全局作用域外, 每一次函数调用都会创建新的名称空间。
- globals() : 返回全局变量的字典,在变量前加上 global 告诉解释器变量为全局变量。
- locals() : 返回局部变量的字典。
- vars() : 返回对象 object 的属性和属性值的字典对象
- 函数嵌套:当需要使用一个函数创建另一个函数时,一个函数写在另一个函数里面,外层函数返回内层函数,也就是函数本身被返回但没有被调用。
def multiplier(factor):
def multiplyByFactor(number):
return number*factor
return multiplyByFactor
double = multiplier(2)
double(5)
multiplier(3)(4)
- lambda表达式:可以创建更短小的函数
my_lambda = lambda x : x + 1
result = my_lambda(123)
- map() : 遍历序列,对序列中每个元素进行操作,最终获取新的序列。
list_1 = [1, 2, 3]
list_2 = [4, 5, 6]
list = map(lambda a, b : a + b, list_1, list_2)
- fliter() : 对序列中的元素进行筛选,创建新的序列。
list_1 = [1, 2, 3]
list = fliter(lambda x : x > 0, list_1)
- reduce() : 将序列的前两个元素与给定的函数联合使用,并将它们的返回值与第三个元素联合使用,知道序列所有元素都处理完。
list_1 = [1, 2, 3, 4, 5, 6]
list = reduce(lambda x, y : x+y, list)
第七章
- 为了上类中的特性或者方法变得私有,只需在它们名字前加上下划线 __ 即可。在类的内部定义中,所有以下划线开始的名字都被翻译成前面加上单下换线加类名的形式,如
s._Secretive__inaccessible()
- 类名称空间(class namespace) : 可由类的所有成员访问。类的定义就是执行代码块,比如,类的定义区中并不仅仅使用def语句。
- issubclass() : 判断一个类是不是另一个类的子类
>>>issubclass(class A, class B)
- 如果想要知道已知类的基类,可以使用__bases__特性。
>>>SPAMFliter.__bases__
- 可以使用 isinstance 检查一个对象是否是一个类的实例。
>>>isinstance(s, SPAMFliter)
- 只是想知道一个对象属于哪个类,可以使用 _class_ 特性
>>>s.__class__
- 多重继承(multi inheritance) : 如果一个方法从多个超类继承,那么必须注意超类的顺序:先继承的超类的方法会重写后继承类中的方法。如果超类们共享一个超类,那么在查找给定方法或特性时的访问顺序称为 MRO (Method Resolution Order)方法判定顺序.
- getattr(object, name, default) : 获取对象object的name特性或者方法。如果是返回是方法,返回的是方法的地址,如果要运行这个方法,
可以在后面添加一对括号 - setattr(object, name, value):设置对象object的特性。如果属性不存在则先创建再赋值。
- hasattr(object, name):判断一个对象中是否有name特性或方法。
第八章
- exception object :Python 用异常对象来表示异常
- raise:为了引发异常,可使用类或者实例参数调用raise, 例如
>>>raise Exception
>>>raise Exception(hyperdrive overload)
- 使用 dir(module) 可列出模块的内容
dir(Exception)
- 如果捕获到异常,但又想重新引发它(传递异常),那么可以调用不带参数的 raise。
- 如果需要用一个块捕捉多个异常,将异常作为元组列出,例如,
>>>except (ZeroDivisioError, TypeError, NameError):
- 如果希望在except子句中访问异常对象本身,可以使用两个参数。在 Python 3 中
except (ZerpDivsionError, NameError) as e:
print(e)
- 可以使用空的except子句捕获所有异常,但这时用
except Exception as e:
会更好些。 - finally子句:用来在可能的异常后进行清理,可以和try连用。
第九章
- 如果一个方法在子类的实例中被调用(或者属性被访问),而在子类中没有该方法,那么就会在它的父类中查找。
class SongBird(Bord):
def __init__(self):
Bird.__init(self)
self.sound = 'Squawks!
在调用一个实例的方法时,该方法的self参数会直接绑定到实例上,这称为绑定方法,但如果直接调用类的方法,而没有实例可以绑定,就可以自有提供self参数,这样的方法称为未绑定(UNbound)方法。- 在将子类和父类关联起来的时候,可使用在子类构造方法中调用
super().__init__()
即使类继承了多个超类。 - 基本序列和映射规则:(附加要求: 如果键是不合适的类型,会引发 TypeError 错误;如果序列的索引是正确的类型,但是超出了范围,会引发 IndexError错误。)
- __len__(self) : 返回集合中所含项目的数量,如果返回0,对象就会被当做布尔变量中的假值来处理。
- __getitem__(self, key)__:这个方法返回所给键对应的值。
- __setitem__(self, key, value)__:这个方法按一定的方式存储键和对应的值。当然,只能为可修改的对象定义这个方法。
- __delitem__(self, key)__:这个方法在一部分对象使用dely语句时被调用,同时必须删除和元素相关的键。
- 属性(property)函数:
size = property(getSize, setSize)
property 可以用0, 1, 2, 3,这4个参数调用,分别被叫做fget, fset, fdel, doc-。 - 静态方法和类成员方法:静态方法和类成员方法在创建时分别被装入 Staticmethod 和 Classmethod 类型的对象中,静态方法没有 self 参数且能够被类本身直接调用。类方法在定义时需要命为 cls 的类似于 self 的参数,类成员方法可以直接用类的具体对象调用,但 cls 参数是直接自动被绑定到类的。
class MyClass:
def smeth():
print("This is a static method.")
smeth = staticmethod(smeth)
def cmeth(cls):
print("This is a class method pf", cls)
cmeth = classmethod(cmeth)
- 装饰器(decorators):它能对任何可调用的对象进行包装,包括函数和方法
class MyClass:
@staticmethod
def smeth():
print("This is a static method.")
@classmethod
def cmeth(cls):
print("This is a class method pf", cls)
>>>MyClass.cmeth()
This is a class method pf <class '__main__.MyClass'>
#可以不用实例化调用方法
- 拦截(intercept)对象的所有特性访问是可能的
- __getattribute__(self, name):当name特性被访问时自动调用(只能在新式类中使用)。也拦截对__dict__的访问。
- __getattr__(self, name):当name特性被访问且对象没有香型特性时时自动调用。
- __setattr__(self, name, vlaue):当试图给name特性赋值时会自动调用。该方法在所涉及到的属性不是‘size’时也会被调用,所以应该把这两方面都考虑进去。
- __delattr__(self, name) : 当试图删除name特性时被自动调用。
class Rectangle:
def __init__(self):
self.width = 0
self.height = 0
def __setattr__(self, key, value):
if key == 'size':
self.height, self.width = value
else:
self.__dict__[key] = value
def __getattr__(self, name):
if name == 'size':
return self.width, self.height
else:
return AttributeError
- 迭代器:__iter__方法返回一个迭代器(iterator), 所谓迭代器就是具有next方法(在调用不需要任何参数,在 Python 3 中是__next__方法)。在调用next方法是迭代器会返回它的下一个值,如果没有值返回,就会引发 StopIterator 异常。内建函数 iter 可以从可迭代对象中获取迭代器。
it = iter([1, 2, 3])
- 生成器(generator):任何包含 yield 语句而不是 return 语句返回结果的函数称为生成器。状态挂起:生成器函数在 yield 语句返回一个值之后,挂起该生成器函数状态,下一次调用时从上一次离开的地方开始(延迟计算,一次只返回一个值)。生成器智能遍历一遍。
- close():手动关闭生成器函数,之后再次调用生成器函数会范湖StopIterator异常。
g.close()
- send() : 生成器函数最大的特点就是可以接受从外部传入的变量,并根据变量内容计算结果后返回。详情请参见 生成器。
g.send(None) #首次调用生成器函数必须传入参数None
g.send('a')
- throw():用来向生成器函数传入一个异常,可以结束系统定义的异常或自定义的异常
g.throw(TypeError)
- close():手动关闭生成器函数,之后再次调用生成器函数会范湖StopIterator异常。
- 生成器表达式:
squares = [x**2 for x in range(5)]
squares = (x**2 for x in range(5))
, 将列表推导的中括号换成圆括号就是生成器表达式。
partial
使用 partial 前要先导入 functools 模块。
一个函数可能有多个参数,在有些情况才有的参数可以先得到,而有些参数需要在后面的情境中才能知道,partial 用于写到部分参数生成一个新的函数
def add(a, b):
return a + b
ps = functools.partial(add, 1)
print(ps(2)) # 3