python核心编程第二版
来源:互联网 发布:linux netstat命令详解 编辑:程序博客网 时间:2024/05/29 23:45
第三章 python基础
模块结构布局
起始行
模块文档
模块倒入
变量定义
类定义
函数定义
主程序main是放置测试代码的好地方
垃圾收集
python解释器会负责跟踪对象的引用计数,当引用计数为0时,垃圾收集器会负责释放内存。垃圾收集器也会负责清理那些虽然引用计数大于0,但也应该被销毁的对象
第四章 python对象
type()的返回值是对象,事实上,type类型是python所有类型的根,也是所有python标准类的元类
用户创建的类实例如果定义了nonzero(nonzero())或length(len())且值为0,那么它们的布尔值就是false
>>> class A(object): def __len__(ob): return 0>>> a = A()>>> bool(a)False
int和str类型是不可改变的,所以python会缓存常用的int类型,当我们试图创建a,b两个值为1的对象时,其实对象并没有被创建,只是引用了已缓存的对象这时候a is b或者id(a)==id(b)的值都是True
第五章 数字
所谓工厂函数是指:这些内建函数都是类对象,当你调用它们时,实际上是创建了一个类实例
第六章 序列:字符串,列表和元组
切片操作:第三个参数是步长,list1[::-1] 视为翻转操作
python默认所有的编码都是ASCII,可以通过在字符串前面加u前缀的方式声明inicode字符串。如果一个unicode字符串被当做参数传给str()函数,那么这个unicode会先被转换成ASCII字符串再交给str()函数,如果该unicode字符串中有不被ASCII支持的字符,会导致异常。而新的内建函数unicode()和unichar()可以看做unicode版本的str()和char(),它们会把python的任何数据类型转换为一个unicode字符串。
unicode和utf-8关系:unicode每个字符要占用两个字节,utf-8是为解决unicode占用空间较大的一种编码方式,utf-8变长编码的,当字符在ASCII码的范围时,就用一个字节表示,保留了ASCII字符一个字节的编码做为它的一部分,注意的是unicode一个中文字符占2个字节,而UTF-8一个中文字符占3个字节)。从unicode到uft-8并不是直接的对应,而是要过一些算法和规则来转换 (https://www.zhihu.com/question/23374078)
unicode字符串处理原则
程序中出现字符串时在前面加u
不要使用str()函数,使用unicode()
不到必要时不使用encode和decode,除非在读写文件或数据库时
pickle模块对unicode的支持很差
当使用%s时,会把字符串中的unicode对象执行str(默认编码)
举例
>>> u'%s %s' %(u'a', 'a')u'a a'>>> a = u'%s' %('哈哈'.decode('gbk'))>>> au'\u54c8\u54c8'>>> print a哈哈>>> u'哈哈'u'\xb9\xfe\xb9\xfe' # gbk编码>>> '哈哈''\xb9\xfe\xb9\xfe'>>> '哈哈'.decode('gbk')u'\u54c8\u54c8' # unicode编码
对list使用 + 会新建一个list,而extend()方法是把新列表加到了原有列表里面
浅拷贝和深拷贝
浅拷贝只是拷贝了对象的引用实现:(1)切片 [:] (2)工厂函数 list() dict()(3)copy.copy()深拷贝copy.deepcopy()
第八章 条件和循环
条件表达式(三元操作符): x if y else z
迭代器
迭代器是一种支持next()操作的对象。它包含一组元素,当执行next()操作时,返回其中一个元素;当所有元素都被返回后,生成一个StopIteration异常。生成器是一种迭代器,是一种特殊的函数,使用yield操作将函数构造成迭代器。普通的函数有一个入口,有一个返回值;当函数被调用时,从入口开始执行,结束时返回相应的返回值。生成器定义的函数,有多个入口和多个返回值;对生成器执行next()操作,进行生成器的入口开始执行代码,yield操作向调用者返回一个值,并将函数挂起;挂起时,函数执行的环境和参数被保存下来;对生成器执行另一个next()操作时,参数从挂起状态被重新调用,进入上次挂起的执行环境继续下面的操作,到下一个yield操作时重复上面的过程。迭代器不能向后移动,不能回到开始,也不能复制 reversed()函数会返回一个反序访问的迭代器,enumerate()也会返回一个迭代器创建迭代器list_a = [1,2,3]i = iter(list_a)i.next()对字典创建迭代器myDict.iterkeys() myDict.itervalues() myDict.iteritems()对文件创建迭代器f = open('file', 'r')for eachline in f: print eachline # 这样会自动调用readline()方法
列表解析
在一定程度上,列表解析可以取代map()和lambda,而且效率更高[x ** 2 for x in range(10) if x % 2][(x, y) for x in range(10) for y in range(10)]
生成器表达式
生成器表达式是列表解析的一个扩展,列表解析的一个不足是必须一次创建整个list。生成器表达式的使用方法和列表解析很相似,但是并不真正创建list,而是返回一个生成器。((x, y) for x in range(10) for y in range(10))
第十一章 函数和函数式编程
python中的过程就是函数,因为解释器会隐式的返回None。没有返回值的函数也会隐式返回None
函数式编程
lambda
a = lambda x, y:x + y
filter() 不管他,用列表解析吧
map() 不管他,用列表解析吧
reduce():取出序列的前两个数,返回结果,与第三个数做运算,以此类推
reduce((lambda:x, y:x + y),range(5))
第十二章 模块
名称空间
a.py www = 'abc'def show(): print wwwb.py from a import www,showwww = '123' # 这是不改变a的www的值的show()import aa.www = '123' # 这是改变a的www的值的a.show()这里所说的改变,指的是模块a的名称空间里www的值,不是a.py文件里www的值
包
init 里面的 all 指定 from a import * 时会导入的模块
绝对导入:必须使用sys.path中的路径
相对导入:from ..a import b
第一个据点标明是相对导入
from a import * 不会导入以 _ 开始的属性
PYTHONCASEOK环境变量指定不区分大小写的导入
当遇到循环导入的问题时,可以把其中一个导入写到函数的内部,解决导入失败的问题
第十三章 面向对象编程
self参数代表的是实例对象本身,类中的一般方法需要这个参数,而类中的静态方法或类方法不需要 __init__ 方法类似于类构造器,在实例化的过程中,__init__ 方法会被调用 dir(Myclass)返回对象属性的一个名字列表,而Myclass.__dict__返回的是一个字典。vars(Myclass)实现了Myclass.__dict__ 类的特殊属性 Myclass.__name__ 类名 Myclass.__doc__ 文档字符串 Myclass.__bases__ 其父类构成的元组 Myclass.__dict__ 类的属性 Myclass.__module__ 类所在的模块 Myclass.__class__ 实例对应的类__new__方法在 __init__方法之前被调用,它比__init__更像一个构造器,暂时没用到 __del__ 解构器,用它干嘛,不用 在类属性中有静态变量的时候,实例会直接访问类的静态变量,在实例中改变这个静态变量的值,会影响到类属性,这个要小心 静态方法,不需要传参数 @staticmethod def foo(): print 'a' 类方法,传递cls作为参数 @classmethod def foo(cls): print 'a'实例方法,传递self作为参数 def foo(self): print 'a' class C(P): def __init__(self): super(C, self).__init__() # 这样能调用C的父类的__init__ 使用__new__方法返回两位小数 class RoundFloat(float): def __new__(cls, val): return super(RoundFloat, cls).__new__(cls, round(val, 2))issubclass() # 判断一个类是否是另一个类的子类isinstance() # 判断一个对象是否是给定类的实例hasattr() getattr() setattr() delattr() # *attr系列方法操作给出的对象和属性13.13 用特殊方法定制类简单定制# coding:utf-8class RoundFloatManual(object): ''' 保留两位小数 上面的__new__ 实现保留两位小数的例子,因为继承自float,所以__str__等方法不需要自己去实现,少踩好多坑 ''' def __init__(self, val): assert isinstance(val, float), "value must be a float" # 断言,判断输入是否为float类型 self.value = round(val, 2) # a = RoundFloatManual(2.033),当你实现__str__方法后,print a 显示的是 str(self.value),否则显示的是实例对象 def __str__(self): return str(self.value) # a = RoundFloatManual(2.033),当你实现__repr__方法后,RoundFloatManual 显示的是 str(self.value),否则显示的是实例对象 # __repr__ = __str__ 这样写的另一个好处是,DRY __repr__ = __str__ 数值定制# coding:utf-8class Time60(object): ''' 操作时间, 精确到小时和分 ''' def __init__(self, hr, min): self.hr = hr self.min = min def __str__(self): return '%d:%d' %(self.hr, self.min) __repr__ = __str__ def __add__(self, other): '''重载运算符 +''' # self.class 代表实例化的类,调用self.class与调用Time60()是一样的 return self.__class__(self.hr + other.hr, self.min + other.min) def __iadd__(self, other): '''重载 += 运算符''' self.hr += other.hr self.min += other.min return self # 重载 __i*__时必须返回self私有化__ 双下划綫开始的属性,在运行时会将类名加到属性前,这更多的是防止同名冲突_ 单下划线开始的属性,来防止from a import *,这是基于作用域的,所以也适用于类授权getattr(my_class, "class_function")和my_class.class_function调用的都是 __getattr__方法。授权的关键就是覆盖__getattr__方法。__getattr__的工作方式是:当搜索一个属性时,先搜索局部字典,再搜索类名称空间,如果都没有搜索到,则调用__getattr__方法处理新式类的高级特性isinstance(obj, int)并没有进行严格的匹配,如果obj是一个给定类型的实例或其子类的实例,也会返回True。严格匹配使用is__slots__属性,可以替代__dict__,使用__slots__时用户不能增加__slots__中不存在的属性,并且节约内存__getattribute__,使用这个函数对类的属性做访问,先不管property :更好的控制对实力属性的访问,没找到场景,略元类和__metaclass__元类用来定义某些类是如何创建的在执行类定义时,解释器会去寻找类属性__metaclass__(还有其他步骤,略),将这个属性赋值给此类作为元类元类是为程序员服务的,它可以强制程序员在定义类时做某些操作# coding:utf-8from time import ctime# 一个类的定义过程,其实就是完成某些工作print "start Metac"class MetaC(type): def __init__(cls, name, bases, attrd): super(MetaC, cls).__init__(name, bases, attrd) print "create class %r at: %s" %(name, ctime())print "\tClass Foo next"class Foo(object): __metaclass__ = MetaC # 在定义类的时候,这里就执行了。__init__需要在实例化的时候才执行 def __init__(self): print "instantiated class %r at:%s" %(self.__class__.__name__, ctime())print "\tClass Foo instantiation next."f = Foo()print "\tDone"
第十四章 执行环境
call : 在类中实现call方法后,类实力就成为可调用的对象,调用的就是call
callable(a) :判断a是否可以通过函数操作符()调用
compile() 允许在运行时声称函数对象,然后通过eval() , exec()等执行可求值表达式,和eval()一起使用eval_code = compile('100 + 200', '', 'eval')eval(eval_code)单一可执行语句,和exec()一起使用single_code = compile('print "hello"', '', 'single')exec(single_code)可执行语句组,通过exec()执行exec_code = compile('''for i in range(10): print i''', '', 'exec')exec(exec_code)
第十八章 多线程编程
进程:进程是程序的一次执行,每个进程都有自己的地址空间,内存等,操作系统管理这些进程,为这些进程公平的分配时间
线程:线程运行在一个进程中,共享运行环境,对于单CPU,每个线程也是被安排成执行一小会
对一些例子做的测试和注释
1.基本使用# coding:utf-8import threadingfrom time import sleep, ctimeloops = [4, 2]def loop(nloop, nsec): print 'start loop', nloop, 'at:', ctime() sleep(nsec) print 'loop', nloop, 'done at:', ctime()def main(): print 'starting at:', ctime() threads = [] nloops = range(len(loops)) for i in nloops: t = threading.Thread(target=loop, args=(i, loops[i])) # target 函数入口 threads.append(t) for i in nloops: threads[i].start() # 开始线程执行 for i in nloops: threads[i].join() # 程序挂起,直到线程结束 print 'all DONE at:', ctime()if __name__ == '__main__': main()2.传一个实例作为线程启动的时候执行# coding:utf-8import threadingfrom time import sleep, ctimeloops = [4, 2]class ThreadFunc(object): def __init__(self, func, args, name=''): self.name = name self.func = func self.args = args def __call__(self): self.func(*self.args)def loop(nloop, nsec): print 'start loop', nloop, 'at:', ctime() sleep(nsec) print 'loop', nloop, 'done at:', ctime()def main(): print 'starting at:', ctime() threads = [] nloops = range(len(loops)) for i in nloops: t = threading.Thread(target=ThreadFunc(loop, (i, loops[i]), loop.__name__)) threads.append(t) for i in nloops: threads[i].start() for i in nloops: threads[i].join() print 'all DONE at:', ctime()if __name__ == '__main__': main()
- Python核心编程(第二版)
- 《Python 核心编程》 第二版
- python核心编程第二版
- Python核心编程第二版学习笔记
- python 核心编程第二版 9-9
- 《Python核心编程(第二版)》pdf
- 《Python核心编程》第二版学习总纲
- 《Python核心编程(第二版)》引读
- 《python 核心编程第二版》第五章
- python 核心编程 第二版 第二章 练习题
- Python核心编程 第二版 第二章 部分习题解答
- 《python核心编程第二版》第二章练习答案解析
- python核心编程 第二版 第二章 习题
- python核心编程第二版第二章习题
- Python核心编程(第二版)第二章练习题
- <python 核心编程第二版课后习题>第二章
- python核心编程第二版第二章学习笔记
- 《Python核心编程》第二版--第三章 Python基础
- PHP
- iOS导航栏切换界面时隐藏和显示
- 前一日函数PreDate(static方法与非static的区别)
- 数据结构--排序算法(冒泡排序&&快速排序&&鸽巢排序)
- 环形缓冲区
- python核心编程第二版
- 495_自定义饼状图
- C语言中结构体的三种初始化方式以及结构体作为传参传递
- 为什么静态方法中不能使用this和super关键字
- JavaScript基础之语法
- 模板以及泛型编程
- stub/skeleton 极简理解
- Unsupported major.minor version (jdk版本错误)解决方案
- spark学习13之RDD的partitions数目获取