流畅的python第1章笔记
Python数据模型
1.doctest模块是测试代码中在注释内的以>>>
开头的所在行的python语句正确性的模块
2.特殊方法的存在是为了被python解释器调用的,你自己不需要调用它.例如,没有my_obj.__len__()
这种写法,而应该用
len(my_obj)
,在执行len(my_obj)
时,如果my_obj
是一个自定义类的对象,那么python会自己调用其中由你实现的
__len__
方法
3.如果是python内置类型,如list,str,bytearray(字节序列),那么CPython会抄近路,__len__
实际上会直接返回PyVarObject里
的ob_size
属性,直接读取这个值比调用一个方法要快很多
4.很多时候,特殊方法是隐式的,比如for i in x:
这个语句,背后其实用的是iter(x)
,而这个函数的背后则是
x.__iter__()
方法,当然前提是这个方法在x中被实现了
5.Python有个内置函数repr
,它能把一个对象用字符串的形式表达出来以便辨认,这就是”字符串表示形式”,repr就是通过
__repr__
这个特殊方法来得到一个对象的字符表示形式的,如果没有实现__repr__
,当我们在控制台里打印一个向量的实例时,
得到的字符串可能会是<Vector object at 0x10e100070>
.通常eval(repr(obj))和obj是等同的.%r
可获取对象各个属性的标
准字符串表示形式.
6.repr()
和str()
的对比:
repr()得到的结果是给python看的,方便调试和记录日志
str()得到的结果是用户看的,方便给终端用户看
如果一个对象没有__str__函数,而python又需要调用它时,解释器会用__repr__作为替代
import datetime
d=datetime.date.today()
print("%s" % d)
print("%r" % d)
输出:
2017-11-20
datetime.date(2017,11,20)
7.bool(x)的背后是调用x.__bool__()
的结果;如果不存在__bool__
方法,那么bool(x)会尝试调用x.__len__()
,若返回0,则
bool会返回False,否则返回True.
None==[]==()=={}==False? ====> 不是的
而是:
bool(None)==bool([])=bool(())==bool({})==False
8.在python中,输入import this会弹出python之禅
9.len之所以不是一个普通的方法,是为了让python自带的数据结构可以走后门,因为如果x是一个内置类型的实例,那么len(x)会通 过CPython直接从一个C结构体里读取对象的长度得到,完全不会调用任何方法,获取一个集合中元素的数量是一个很常见的操作,在 str,list,memoryview等类型上,这个操作必须高效
10.通过实现特殊方法,自定义数据类型可以表现得跟内置类型一样,从而让我们写出更具表达力的代码.如:
class FrenchDeck:
ranks=[str(n) for n in range(2,11)]+list('JQKA')
suits='spades diamonds clubs hearts'.split()
def __init__(self):
self.cards=...
def __len__(self):
return len(self._cards)
def __getitem__(self,position):
return self._cards[position]
11.python的四个魔法方法