1.
装饰器(Decorator)简单的说就是装饰函数的函数,使得返回一个被修饰后的新函数。
三篇很好的文章:
http://www.cnblogs.com/huxi/archive/2011/03/01/1967600.html
http://blog.csdn.net/thy38/archive/2009/08/21/4471421.aspx
http://www.codecho.com/understanding-python-decorators/
2.
可以对诸如List tuple dict 这种内建类型子类化,当需要功能相似的类时最好就子类化他们。
3.
老的MRO在查找方法所属的类时从继承的基类中按照“从左到右深度优先”,而新的MRO(2.3版本后)采用C3的线性化方法
class basebase(): def method(self): print "basebase" class base1(basebase): pass class base2(basebase): def method(self): print "base2" class myclass(base1, base2): pass here = myclass() here.method()
class basebase(object): def method(self): print "basebase" class base1(basebase): pass class base2(basebase): def method(self): print "base2" class myclass(base1, base2): pass here = myclass() here.method()
类查找的顺序是
myclass base1 base2 basebase object
4.
基类不会在__init__中被隐式调用
5.
mro记录了一个类的所有基类的类类型序列。
类的__mro__特性,储存线性化计算的结果,可以简单的理解为类继承时的查找顺序。
6.
super并不是一个函数,是一个类名,形如super(B, self)事实上调用了super类的初始化函数, 产生了一个super对象;
super类的初始化函数并没有做什么特殊的操作,只是简单记录了类类型和具体实例;
super(B, self).func的调用并不是用于调用当前类的父类的func函数;
Python的多继承类是通过mro的方式来保证各个父类的函数被逐一调用,而且保证每个父类函数只调用一次(如果每个类都使用super);
混用super类和非绑定的函数是一个危险行为,这可能导致应该调用的父类函数没有调用或者一个父类函数被调用多次。
非绑定指的是如
A.__init__(self)
个人理解super的作用类似于寻找当前类的父类,然后加入到一个列表中,并按照这个列表中的顺序依次调用函数。这个列表就存在mro中。
在使用时应该保持一致性,要用都用,要不用全部不用。
7.
通常用“_”前缀表示类中不公开的特性,而不用“__”
8.
在Python中,访问一个属性的优先级顺序按照如下顺序:
1:类属性
2:数据描述符
3:实例属性
4:非数据描述符
5:__getattr__()方法
9.
描述符(descriptor)分为数据描述符和非数据描述符。数据描述符实现了__get__,__set__,__delete__三个方法的类
set是在对属性赋值时进行修改。
get是这个属性返回时就行的操作。
delete是回收时的操作。
class simpleDescriptor(object): def __init__(self): self.result=None; def __get__(self,obj,type=None) : return self.result-10; def __set__(self,obj,val): self.result=val+3; print self.result; def __del__(self,obj): pass class A(object): foo=simpleDescriptor(); a=A(); a.foo=13; print a.foo;
16
6
没有实现 set del的就是非数据描述符。所有的函数都是非数据描述符
参考:http://onlypython.group.iteye.com/group/wiki/1362-python-39-s-descriptor
10.
__slots__槽 特性为指定的类设置一个静态列表,从而跳过每个类实例中的__dict__的创建,这样就节省了空间。无法在派生类上工作
class Frozen(object): ice = 1 cream = 1 pass print '__dict__' in dir(Frozen) print 'ice' in dir(Frozen) ga = Frozen() ga.ice = 2 ga.cream = 2 ga.icy = 3 print ga.ice, ga.cream, ga.icy
True
True
2 2 3
class Frozen(object): __slots__ = ['ice','cream'] print '__dict__' in dir(Frozen) print 'ice' in dir(Frozen) ga = Frozen() ga.ice = 2 ga.cream = 2 ga.icy = 3 print ga.ice, ga.cream, ga.icy输出为
False
True
Traceback (most recent call last):
File "/home/zawdd/workspace/MyPython/project1/chapter3.py", line 55, in <module>
ga.icy = 3
AttributeError: 'Frozen' object has no attribute 'icy'
11
dir()显示一个类的所有有效属性
12
没有__dict__属性,所以没办法在它们上面附加自定义属性,如list,string。
13
函数也是对象,函数是函数,方法是方法,方法又分为instancemethod ,classmethod,staticmethod
class T(object): def hello1(self): print "hello1" def hello2(): print "hello2" hello2 = staticmethod(hello2) def hello3(cls): print "hello3", cls hello3 = classmethod(hello3) t = T() t.hello1() t.hello2() t.hello3() #AttributeError: 'T' object has no attribute 'hello3' print t.hello1 #<bound method T.hello1 of <__main__.T object at 0xb71f38cc>> print t.hello2 #<function hello2 at 0xb7289144> print t.hello3 #<bound method type.hello3 of <class '__main__.T'>> #T.hello1()#unbound method hello1() must be called with T instance as first argument (got nothing instead) print " " T.hello2() T.hello3() print T.hello1 #<unbound method T.hello1> print T.hello2 #<function hello2 at 0xb734e144> print T.hello3 #<bound method type.hello3 of <class '__main__.T'>>staticmethod使方法变成了函数,从而不需要第一个self参数
14
type() 接受名字,基类和属性作为参数,返回一个类
__metaclass__ 用以修改或增加类的新特性
metaclass的实例化结果是类,而class实例化的结果是instance(通过调用__new__创建类)
参考:http://jianpx.iteye.com/blog/908121
15
遵照PEP 8命名约定
命名时用前导下划线表示私有,方法和函数用小写加下划线
双下划线表特殊
类用大写首字母的命名方式
模块名称使用不带下划线的小写字母,当对于包私有时,加前导下划线
为了防止名称重复,可在后面加下划线class 常写作klass 或cls
16.
对于已经发布的API,在修改时,遵循deprecation过程,在1,2版本之间,加入一个1.5版本,在该版本中进行修改的提示
使用warning模块达到这一目的
17.
为了避免Python被污染,应用程序级别的工作环境应该能够将用于应用程序的所有依赖模型隔开。
可以使用virtualenv来在已有Python上创建一个新的,独立的Python解释程序
python2.7中可以通过每个用户使用独立的site-packages来实现。