之前在上海的时候,认识了一个python大神,之后一直有关注过这个大神,还总看他的博客,大概在一月份的时候,发现他在某个视频公开课上的python课程,抱着膜拜的态度,我买了这个公开课(大概300多元),即使是面向初学者的,我还是能从中学到一些知识,所以我把那些我认为值得总结的知识点,作为学习笔记,记录一遍。
几个类型问题
在python中u”hellow” == “hellow” 是True,但是 u”中文” != “中文”,之所以unicode能和str比较,是因为内部在比较的时候,做了类型转换。
int/int结果还是int,因为运算要让类型封闭。
dict的get方法,比[]要安全很多。
[] != None
函数
1 | def a(*argc, **kargc): |
调用的时候,传入列表可以用*可以解开, **可以解开字典。
作用域规则
在python中,print
既是个函数,又是个关键字:你可以: getattr(__builtins__, "print")
对于一个函数,会先在local中寻找,然后在environmental(闭包中),然后再在global中寻找,最后再在__builtins__中寻找。
1 | a = 0 |
一旦变量被定义了,那就只在local中查找,所以上面那个调用f会报错。
有两个常用的内建函数:
1 | hasattr(对象, 'xxx') |
关于python类
python的哲学是,调用者要保证做正确的事,而不是编写者保证。
__
双下划线,就会隐藏。
_xxx
不能用’from moduleimport *’导入 ,一般不会在类中使用的,而是放在模块中。
__xx__
这种也不会使用,因为这是python系统内部的定义。
1 | class D(B): |
你可以用如上的方式调用父类的构造函数,一些人建议你用super,一些人不建议用。
1 | Help on class super in module __builtin__: |
作为一个对象的函数,可以使用类,直接绑定替换:
1 | class D(B): |
但不能使用对象替换(d = D(), 既d),因为在python中,类的成员在变为对象的成员时,会进行一次包装,类似于传入self,然后使所有方法绑定到self
所以不在类上绑定,就只能: d.func = lambda num: d.num + num
打印dir(d),可以发现,func是一个包装对象
1 | d.func.im_class:它的类 |
python的 @property
包装一个属性的读,写,删除操作,也可以在其中添加一些操作。
python多继承,Mixin模式,方便的绑定一个或者多个,进行替换,这些都要精心设计。
闭包和类对象基本是没差异的。
1 | class Out(object): |
但是对于类的共享变量,在闭包中要这样写才可以:
1 | def Out(a, b, c): |
才能共享。一次返回两个函数,才能被共享。
可以用装饰器来实现,flask的path注册。
1 | class Reg(object): |
python 的反模式:
1 | def f(l=[]): |
这样不行
1 | def f(l=None): |
这才是对的,这个在我之前的博客有提到过
几个python内置电池
生成一个随机n位字符串: "".join([random.choice(string.letters+string.digits) for i in xrange(n)])
logger
简单的使用logger
1 | logger = logging.getLogger() |
Counter
collections中的 Counter, 计算字符出现的频度。用来统计,哪些字符出现了多少次。还可以统计单词出现的次数。
contextmanager
1 |
|
打印顺序是 a, c, b
但是系统context有一个坑爹之处。
1 |
|
上面的代码 c就不会被打印了。
所以系统的contextmanager 正确使用方式是:
1 |
|
否则有raise exception 什么也执行不了。
有一篇博客介绍 上下文管理器
流对象
每次取得一个元素
不可跳过下一个元素取得后续元素
不可回溯前一个元素。
流可以一个一个获取,不用一次就全部生成。
可以对流使用过滤器,使用映射。
列表推倒和循环假定不可以并发,函数式隐含可以并发。
函数式风格
大量的使用高阶函数和第一类函数风格
在小幅使用闭包替代微型类
一行流,代码经常写成lisp缩进风格
经常使用“无副作用函数”
偏好递归非迭代。
基本控制结构为函数构造形态。
缺点:函数式的一行流,不适合调试程序。
几个python哲学
duck typing pola
POLA: the principle of least astonishment
错误处理:函数不可能又返回值又返回错误,使用异常处理错误.
尽早出错,不要做输入检测,不要写保护性代码,不要容错,不要处理异常。
不要捕获额外的错误,尤其禁止捕获Exception。
尽量使用python现有异常,比如ValueError,除非有必要做出区分。