Pulpcode

捕获,搅碎,拼接,吞咽

0%

记录一次python视频总结

之前在上海的时候,认识了一个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
2
3
4
5
a = 0

def f():
print a
a = 1

一旦变量被定义了,那就只在local中查找,所以上面那个调用f会报错。

有两个常用的内建函数:

1
2
hasattr(对象, 'xxx')
getattr(对象, 'xxx')

关于python类

python的哲学是,调用者要保证做正确的事,而不是编写者保证。

__双下划线,就会隐藏。

_xxx 不能用’from moduleimport *’导入 ,一般不会在类中使用的,而是放在模块中。

__xx__ 这种也不会使用,因为这是python系统内部的定义。

1
2
3
4
class D(B):
def __init__(self, num):
B.__init__(self, num)
# super(D, self).__init__(num)

你可以用如上的方式调用父类的构造函数,一些人建议你用super,一些人不建议用。

1
2
3
4
5
6
7
8
9
10
11
12
13
Help on class super in module __builtin__:


class super(object)
| super(type) -> unbound super object
| super(type, obj) -> bound super object; requires isinstance(obj, type)
| super(type, type2) -> bound super object; requires issubclass(type2, type)
| Typical use to call a cooperative superclass method:
| class C(B):
| def meth(self, arg):
| super(C, self).meth(arg)
|
| Methods defined here:

作为一个对象的函数,可以使用类,直接绑定替换:

1
2
3
4
class D(B):
pass

D.func = lambda self, num: self.num + num

但不能使用对象替换(d = D(), 既d),因为在python中,类的成员在变为对象的成员时,会进行一次包装,类似于传入self,然后使所有方法绑定到self
所以不在类上绑定,就只能: d.func = lambda num: d.num + num

打印dir(d),可以发现,func是一个包装对象

1
2
3
d.func.im_class:它的类
d.func.im_func: 它的函数指针
d.func.im_self: 它的self函数。

python的 @property

包装一个属性的读,写,删除操作,也可以在其中添加一些操作。

python多继承,Mixin模式,方便的绑定一个或者多个,进行替换,这些都要精心设计。

闭包和类对象基本是没差异的。

1
2
3
4
5
6
7
8
9
10
11
class Out(object):
def __init__(self, a, b, c):
self.a, self.b, self.c = a, b, c
def __call__(self):
print self.a, self.b, self.c


def Out(a, b, c):
def inner():
print a, b, c
return

但是对于类的共享变量,在闭包中要这样写才可以:

1
2
3
4
5
6
7
def Out(a, b, c):
attrs = {}
def i1(n):
attrs['a'] = n
def i2():
print attrs['a']
return i1, i2

才能共享。一次返回两个函数,才能被共享。

可以用装饰器来实现,flask的path注册。

1
2
3
4
5
6
7
8
9
10
11
class Reg(object):
def __init__(self):
self.d = {}

def register(self, path):
def inner(f):
self.d[path] = f
return f
return inner

reg =Reg()

python 的反模式:

1
2
def f(l=[]):
pass

这样不行

1
def f(l=None):

这才是对的,这个在我之前的博客有提到过

几个python内置电池

生成一个随机n位字符串: "".join([random.choice(string.letters+string.digits) for i in xrange(n)])

logger

简单的使用logger

1
2
3
logger = logging.getLogger()
logging.basicConfig(level=logging.INFO)
logger.info("xxxx")

Counter

collections中的 Counter, 计算字符出现的频度。用来统计,哪些字符出现了多少次。还可以统计单词出现的次数。

contextmanager

1
2
3
4
5
6
7
8
9
@contextmanager
def example():
print 'a'
yield
print 'b'

def main():
with example():
print 'c'

打印顺序是 a, c, b

但是系统context有一个坑爹之处。

1
2
3
4
5
6
7
8
9
@contextmanager
def example():
print 'a'
yield
print 'b'
def main():
with example():
print 'c'
raise Exception()

上面的代码 c就不会被打印了。

所以系统的contextmanager 正确使用方式是:

1
2
3
4
5
6
7
@contextmanager
def example():
print "a"
try:
yield
finally:
print "b"

否则有raise exception 什么也执行不了。

有一篇博客介绍 上下文管理器

流对象

每次取得一个元素

不可跳过下一个元素取得后续元素

不可回溯前一个元素。

流可以一个一个获取,不用一次就全部生成。

可以对流使用过滤器,使用映射。

列表推倒和循环假定不可以并发,函数式隐含可以并发。

函数式风格

大量的使用高阶函数和第一类函数风格

在小幅使用闭包替代微型类

一行流,代码经常写成lisp缩进风格

经常使用“无副作用函数”

偏好递归非迭代。

基本控制结构为函数构造形态。

缺点:函数式的一行流,不适合调试程序。

几个python哲学

duck typing pola

POLA: the principle of least astonishment

错误处理:函数不可能又返回值又返回错误,使用异常处理错误.

尽早出错,不要做输入检测,不要写保护性代码,不要容错,不要处理异常。

不要捕获额外的错误,尤其禁止捕获Exception。

尽量使用python现有异常,比如ValueError,除非有必要做出区分。