Python Essential Reference 4th – 第7章 – 读书笔记

1、类(class)和实例(instances)是1对N的关系。

2、class由若干函数、变量(类成员)、属性(实例成员)组成。
一个示例的类如下:

3、类的实例化

4、Python无类作用域,即对实例(无论是函数还是属性)的操作都必须加self完成。

5、python中的继承:基类( base class )、派生类 ( derived class ),派生类继承基类的所有属性和方法,并可以选择重写或移除。object是所有Python对象的基类(和Java的Object一样)。一个继承类的写法很简单,就是在def时class B(A):,A为基类,B为派生类。

而调用是,依然是
c = EvilAccount(“Me”,1500) #继承了基类的__init__方法
c.badwithdraw(1000) #直接定位到派生类
c.withdraw(1000) #派生类没有,定位到基类

6、派生类调用基类构造函数:多数发生在派生类的构造函数与基类参数不同时。

7、派生类如何调用父类的函数:
(1)self.xxx(abcd)
(2)super(cls, instance).xxx(abcd)
例如:

8、Python支持多继承,但属性间的冲突会导致很多问题,所以不建议使用。

9、多态/Duck Typing:Python一直都是运行时决定类型,因此有人称之为Duck Typing,即“鸭式类型”。好处是,可以定义一些内部方法、属性很类似但又无继承关系的类。例如标准库中的file-like文件。

10、静态方法和类方法。
可以说,类方法是静态方法的一个拓展吧(不再局限于类了)

标准的调用方法都一样:
Foo.add(3,4)
Foo.mul(4,5)
除此之外,python并没有限定类方法和静态方法不能用于实例上,因此如下也是合法的:
f = Foo()
f.add(3,4)
f.mul(5,6)

11、属性标记@property,标记后,可以向访问实例属性一样自动get,如下:

如果不加上述@property,则返回值c.radius会被视为是函数area的实例。
m = c.radius #m是函数实例
真正的m()时,才会调用c.radius()

12、一般来说,最好用getter和setter对实例内的属性进行保护,上面的@property只是getter方法,如何实现让函数类似的属性可以被赋值呢?需要@xxx.setter和@xxx.deleter。如下:

标签@area.deleter的.前面的area必须完全匹配@property标记的属性!
这样后,就可以如下用啦!
c = Cicle()
a = c.area
c.area = 123.2
del c.area

13、也可以用用户自定义的get和set方法来做隔离。它们是:__get__()、__set__()、__delete__()函数。

14、关于私有函数/变量。根据Python约定,以下划线_开头的,可视为私有变量,但无明确语法限制。

15、对象的内存管理:创建对象时,会调用class的__new__()和__init__()。
__new__()的用法一般很罕见,主要用途为:
(1)从一些不可变类继承时,在new中更改一些数值,入string,tuple等。

(2)__new__()用于metaclass,后面会讲到

16、对象的管理也是基于引用计数:reference counting。当rc降到0的时候,会删除对象,此时调用自定义的__del__()如果有的话。__del__()一般也无需定义,除非你要显示的关闭文件、关闭网络socket、释放链接等操作。一般这些都不应该在__del__()中完成,和Java的finalize()道理一样。

17、引用计数rc并非完美,又是会产生‘“环引用”,导致内存泄漏,典型的就是“观察者模型”,此时可用弱引用解决问题。

18、默认情况下,python的属性名集合是用dirtionary(类似map)的结构实现的,记录在cls.__dict__中。
当实例的任何属性self.xxx变化时,都会反应到cls.__dict__中。访问属性时,最终会调用内置的__getattr__()、__setattr__()和__delattr__(),如果需要,可以在这三个地方做拦截器(记录日志之类的)。

19、可以替换属性集合的内置数据结构,采用__slot__,它将限定属性可使用的名称,换来更小的内存和更快的运行时间。

由于不使用__dict__,对属性的访问也不会在进入__getattr__()等函数了。
此外,在继承的时候,子类必须也定义__slot__,否则内存消耗会更大!因此继承时候要谨慎使用。

20、python支持重载操作符,例如对加号+的重载如下:

21、检查一个实例是否属于某一类:isinstance(obj,name)
issubclass(A,B):如果类A属于类B,注意A和B都是cls,不是实例。
isinstance和issubclass都是可以重写的,这点上python比较灵活。

22、抽象类:Python支持抽象类,需要引用abc模块。

抽象类肯定是不能直接被实例化的,实现抽象类得方法并不是继承!而是注册,如下:

23、Metaclass,我没看懂 – – 感觉是类似于Java的反射代理机制,用于框架时候比较给力。

24、类包装器Class Decorators: take a class as input and returns a class as output
其实也没太明白用途。。

Leave a Reply

Your email address will not be published.