本系列主要介绍《Effective Python》所推荐的最佳实践,经验丰富的程序员应该对这些实践都比较熟悉了。文中有些补充信息是我自己的理解,请大家多指教!具体分析还请参考原书内容。

本系列集合地址:

读书录​blog.kantli.com


三:类与继承(7条建议)

1. 尽量用辅助类维护程序状态,不要用字典和元组;

如果保存内部状态的字典变得比较复杂,应该拆解为多个辅助类。

2. 简单的接口应该接受函数,而不是类的实例;

在 Python 中,函数是一等对象(first class),可以作为参数传递,我们可以利用这个特性简单实现策略模式(有需要可以参考上一个系列的文章:Python与设计模式),典型的例子是 sorted()方法。

不过,传递函数的情况只适用于比较简单的状态,如果需要保存状态,用函数也可以实现,即使用闭包,但可读性会差一些,建议还是使用辅助类。实现 __call__ 方法之后的类,实例是可调用的。

3. 以 @classmethod 形式实现类的多态;

一般只用 _init_ 方法,不够用的时候可以用这个方法添加构造器。

4. 用 super() 初始化父类;

多重继承情况下,直接调用父类进行初始化可能会出现冲突,super() 经过特殊处理,可以根据方法解析顺序进行初始化。

5. 只在使用 Mix-in 形式组件制作工具类时进行多重继承;

设计原则:多用组合,少用继承。

6. 多用 public 属性,少用 private 属性;

理论上说,Python 中的类属性前加两个下划线就是私有属性,使用者没法直接调用。但如果确实要调用,也有绕过规则的办法,所以,Python 的私有属性是不严格的。实践中一般用单下划线前缀表示受保护的属性,不是特殊情况不允许调用,也算一种社区“潜规则”。

使用私有属性的问题是,之后要继承这个类进行扩展或优化的时候,调用这个属性很麻烦,因此一般认为是得不偿失的。作者建议,只有在子类不受自己控制时,才用私有属性避免命名冲突。

7. 实现自定义容器时,应该继承 collections.abc 里的抽象基类;

作者的观点是,简单的容器还是直接继承 Python 的容器类型,比如列表或字典,比较复杂时可以继承抽象基类,主要理由是可以少写一些方法。


四:元类与属性(7条建议)

1. 用纯属性取代 get 和 set 方法;

@property | @attr_name.setter | @attr_name.getter 来替代其它语言中的 gettersetter

2. 考虑用 @property 来代替属性重构;

取消旧属性的时候,可以考虑用这个修饰器来支持调用原来的类的旧代码继续运作,但这个修饰器用得多了,显然也不合理,最后还是要重构旧代码的。

3. 用描述符来改写需要复用的 @property 方法;

描述符类即实现了__get____set____del__ 方法的类,用描述符类来改写一些属性方法比较少见,而且似乎并不直观,不过,作者的观点理论上是对的。

4. 用 __getattr____getattribute____setattr__实现按需生成的属性;

这个地方需要注意,长相上看,__getattr____setattr__比较像,但__getattr__ 是在检查实例字典,并且没有找到对应值之后才调用的,__getattribute____setattr__则会一开始就调用,所以谁和谁是一对比较让人费解。

另外,由于__getattribute____setattr__会在获取和设置属性值的时候直接调用,所以写这两个函数时要小心,避免调用自身,造成无限递归。

5. 用元类来验证子类;

元类是处理类的生成过程的,控制元类的__new__方法,可以对类的生成过程做一些验证。一般情况下,类也可以控制自己的__new__方法,但类自身的__new__方法控制的是实例的生成过程。

加载模块时,Python 会在类的 class 语句处理完毕之后,执行其元类的__new__方法。所以,错误的,或者说,不符合我们需求的类定义语句会在这时被我们验证出来。这个时间点要比调用类生成实例要早多了。

元类是一个比较高级,也比较少用的特性,这里借用《流程的Python》中引用的Tim Peters的一句话:

(元类)是深奥的知识,99%的用户都无需关注。如果你想知道是否需要使用元类,我告诉你,不需要(真正需要使用元类的人确信他们需要,无需解释原因)。

之后的两个建议也都是元类的具体使用场景,理解了元类的概念和具体执行的时间点,自然就好理解了。

6. 用元类来注册子类;

7. 用元类来注解类的属性;

python自定义修饰器_Python进阶自检清单:来自《Effective Python》的建议(二)相关推荐

  1. python自定义修饰器_Python概述

    #Version 3.0 本章主要解决:为什么学Python,Python是什么样的语言,怎么学Python,怎样做老庄才给你及格或优秀. 一.为什么学Python 学习编程要比学习英语更重要,因为编 ...

  2. python函数修饰器_Python函数装饰器指南

    Python 具有强大的功能和富有表现力的语法.我最喜欢的装饰之一.在设计模式的上下文中,装饰器动态更改方法或类功能,而不必直接使用子类.当您需要扩展功能,但不想修改原函数时,这是理想的选择.我们可以 ...

  3. python 函数修饰器 父类_手把手教你学python第十四讲(函数装饰器,super用法和时间处理)...

    文中有些字在图中是因为每篇文章最多100张图片,我把有的小图片和文字一起截图了,文中所有的引用都会标出原文网址,除此以外都是作者原创. 有时候会在文章最前或者最后补充一些知识或者把前面说的有问题的地方 ...

  4. python 自定义模块加密_Python开发【第一篇】Python基础之自定义模块和内置模块...

    为什么要有模块,将代码归类.模块,用一砣代码实现了某个功能的代码集合. Python中叫模块,其他语言叫类库. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代 ...

  5. python类修饰器_Python 中使用类修饰器修饰类方法如何处理 self?

    这个是装饰器类. class PostCache: def __init__(self, func): self.func = func self.redis = redis.StrictRedis( ...

  6. python中修饰器_python 中的修饰器

    参考文章 @property和@ .setter的用法: @property 把属性装饰成get方法 给属性赋值时,会自动调用@property装饰的方法 只设置属性的@property 时,属性为只 ...

  7. 图解Python多修饰器时哪个先起作用

    修饰器本质上是一个函数,它接收一个函数作为参数并返回一个修饰过的新函数,一般来说不会改变函数的功能,只是在外围增加一些辅助性的检查或小功能. 在拙作<Python程序设计开发宝典>中有下面 ...

  8. python修饰器_python修饰器

    转自:http://www.cnblogs.com/rollenholt/archive/2012/05/02/2479833.html 文章先由stackoverflow上面的一个问题引起吧,如果使 ...

  9. python修饰器_python设计模式之修饰器模式

    python设计模式之修饰器模式 无论何时我们想对一个对象添加额外的功能,都有下面这些不同的可选方法. [ ] 如果合理,可以直接将功能添加到对象所属的类(例如,添加一个新的方法) [ ] 使用组合 ...

  10. python中修饰器的优点和作用_Python装饰器(你想知道的这里都有)

    1. 装饰器的定义 就是给已有函数增加额外功能的函数,它本质上就是一个闭包函数. 装饰器的功能特点: 不修改已有函数的源代码 不修改已有函数的调用方式 给已有函数增加额外的功能 闭包和装饰器的区分: ...

最新文章

  1. 干掉cms,zgc才是未来
  2. Comparable与Comparator用法详解
  3. 简述systemd的新特性及unit常见类型分析、使用systemd管理编译安装的nginx
  4. Sequelize 4.42.1 发布,基于 Nodejs 的异步 ORM 框架
  5. 将datatable导出为excel的三种方式(转)
  6. 30.课时30.【Django模板】autoescape标签使用详解(Av61533158,P30)
  7. Tarjan+topsort(DP)【P3387】 [模板]缩点
  8. 03-SSH server config
  9. 【新星计划】怎么写好技术博客?
  10. NXOPEN/UG二次开发C#---获取NX的版本
  11. word中公式和文字不在一行的设置方法
  12. 从函数式编程到Promise
  13. vgs是什么意思有什么用_Linux中vgs命令起什么作用呢?
  14. JDBC实现多条件查询万能解决思路
  15. 淘宝订单接口|订单插旗备注,淘宝开放平台最稳定的店铺订单接口
  16. php生成字母头像,Identicon:实现根据用户账号生成像素头像 php 版
  17. 最长公共子序列(LCS)C++版递归算法实现
  18. 【附白皮书下载】制造业数字化转型专家黄正杰:设备健康如何管理?
  19. 纯函数和副作用(大白话)
  20. android 录制屏幕 带声音 可直播方案 截屏

热门文章

  1. CocoaPods报错:The dependency 'xxx' is not used in any concrete target
  2. 由世纪互联运营的 Windows Azure 现已在中国正式发布
  3. 谈谈jdmailgate邮件wg在企业中的角色扮演
  4. exists/not exists(2020-3-27)
  5. 打开gedit_使用 gedit 文本编辑器优化你的 GNOME 体验 | Linux 中国
  6. 【转】Element-UI中上传的action地址相对问题
  7. .NET中的Lambda表达式与匿名方法
  8. 让Windows Server 2008+IIS 7+ASP.NET支持10万个同时请求
  9. Spring知识点总结
  10. 『TensorFlow Internals』笔记_系统架构