这章延续第1章内容,探讨如何实现很多Python类型中常见的特殊方法。这些特殊方法我觉得可以看成一种特别的“钩子”。Python内部设计的远比PHP/JavaScript语言严谨、精巧、精细,它定义了对象的各种各样的运算方式,这些方式在内部用特殊方法实现。如果你自定义的对象要支持这些运算,或者要更改默认的操作方式,就可以设定“钩子”,拦截这些调用即可。

举例:

hash(object1) -> object1.__hash__

format(object1) -> object1.__format__

Bool(object1) -> object1.__bool__

 

repr() – 以便于开发者理解的方式返回对象的字符串表示形式。

str() – 以用户理解的方式返回对象的字符串表示形式。

在Django框架里面,每个model都建议定义str()字符串表示的实现。因为你在admin管理系统里面会看到对这个model方法的调用,很有用处。

Python提供了classmethod和staticmethod装饰器。熟悉C++/Java面向对象设计的人很容易理解,就是定义类方法和静态方法。它们两个的区别是,classmethod第一个参数会是类本身,常见用途是定义备选构造方法。对于staticmethod,个人建议谨慎使用。因为我遇见过使用staticmethod装饰的方法,Python运行时产生内存泄漏、对象无法回收的情况,很难追查。

与C++/Java等比较严格的面向对象语言不同,Python没有定义对象的私有属性,以后也别想,因为这么弄动态语言太累了。但是属性确实要做一些保护如何处理?Python提供了一个规则:使用“__”双下划线作为前缀。这是一种约定,称为“名称改写”,并不是严格意义上的保护措施。

对于大量使用的对象,可以考虑自定义__slots__保存属性,避免Python默认使用__dict__,可以节约大量的内存。不过相关的限制需要了解下。

 

流畅的Python-Fluent Python读书笔记-10-序列的修改、散列和切片
流畅的Python-Fluent Python读书笔记-08-对象引用、可变性和垃圾回收