本笔记完全基于David Beazley的Python教程-Practical Python.
Debugging
调试的开始都是从Traceback开始.当Python程序方程未补货异常的时候,解释器就会打印Traceback(错误回溯),他包含调用栈(函数是如何一层层调用到出错位置的),精确的出错行号,异常类型和异常信息.
本笔记完全基于David Beazley的Python教程-Practical Python.
调试的开始都是从Traceback开始.当Python程序方程未补货异常的时候,解释器就会打印Traceback(错误回溯),他包含调用栈(函数是如何一层层调用到出错位置的),精确的出错行号,异常类型和异常信息.
本笔记完全基于David Beazley的Python教程-Practical Python.
logging模块解决的是一个工程级别的诊断信息管理问题:如何在不污染业务逻辑的前提下,记录那些对程序分析有用的信息,并且允许用户自行决定是否查看这些信息.这个之前我们其实也有一些做法,我们将其罗列在下面的表格
| 做法 | 问题 |
|---|---|
| print() | 无级别,无法关闭,无法重定向 |
| pass | 丢失执行信息,丢失诊断信息 |
| logging | 可分级,可配置,可集中管理 |
所以对于日志模块而言,强调的是行为(记录日志)和策略(如何输出)分离.因此logging的设计是分层的,其中有Logger,Handler,Formatter和Filter.
本笔记完全基于David Beazley的Python教程-Practical Python.
Python动态特性使得测试对大多数程序至关重要.编译器的静态编译并不能帮你查到程序错误,唯一发现错误的方式就是运行代码,并确保测试了他的所有功能.
本笔记完全基于David Beazley的Python教程-Practical Python.
我们之前介绍了装饰器和一些Python预定义的装饰器.这些预定义装饰器是用于在类中定义中指定特殊类型的方法.一般有staticmethod,classmethod和property.其中property,我们前面已经介绍过了property,他将类中的方法伪装成属性.通过property,可以在保持对象接口简洁的同时,对属性访问进行控制.
本笔记完全基于David Beazley的Python教程-Practical Python.
在Python中,函数和整数,字符串一样都是对象.因此函数可以作为另一个函数的返回值,函数可以赋值给变量,函数可以作为参数传递.如
1 | def add(x,y): |
这里的add函数并没有执行加法,而是返回了一个执行加法的新函数do_add.这里的变量a指向的是函数do_add,因此可以用a()的方式来调用内部函数.
本笔记完全基于David Beazley的Python教程-Practical Python.
在我们前面介绍的函数模型中,函数的调用参数是固定的:
1 | def f(a,b,c): |
这表示函数的参数数量固定,参数名称固定,外部调用必须要严格匹配.一旦程序需求变化,那么接口就会破坏兼容性.因此为了解决这一问题,Python引入可变参数,为了满足如下三个目标:接口数量稳定,调用方式自然以及函数内部能统一处理参数集合.
本笔记完全基于David Beazley的Python教程-Practical Python.
生成器generator是用来设置各种生产者/消费者问题和管道工具的解决方案.生产者-消费者问题是经典的并发问题之一,其基本思想是生产者负责产生数据;消费者则负责使用数据;两者之间通过某种缓冲区或者管道的方式进行数据交换.Python中的生成器则很适合实现这种模式,他们具有延迟求值的特性:生成器不会一次性返回所有数据,而是每次yield产生一个值给消费者.
本笔记完全基于David Beazley的Python教程-Practical Python.
在前面的讨论中,我们多次使用了容器迭代的程序,但是我们并没有深入了解过的迭代循环的底层实现,因此我们在此先介绍他的底层实现.
1 | _iter=obj.__iter__() |
这里的obj表示一个可迭代对象,而_iter则表示迭代器对象.根据上面的底层实现来看,循环迭代的行为是基于迭代器对象.
本笔记完全基于David Beazley的Python教程-Practical Python.
类的使用会试图封装内部实现细节.因为类的主要作用之一是封装对象数据和内部实现细节,但是会提供一些public接口供外部调用.这一特点在C++体现的尤为明显,他通过严格的访问控制机制来实现代码的封装.但是Python中并没有提供严格的封装机制以及访问控制机制.