Python 高级编程(第2版)--第3章 语法最佳实践 -- 类级别以上

语法最佳实践 – 类级别以上

子类化内置类型

  • Python 有一个叫作 object 的内置类型,它是所有内置类型的共同祖先,也是所有没有显式指定父类的用户自定义类的共同祖先。需要实现与某个内置类型具有相似行为的类时,最好的方法就是将这个内置类型子类化。

访问超类中的方法

  • super 是一个内置类,可用于访问属于某个对象的超类的属性。
  • super 的简化形式(不传入任何参数)可以在方法内部使用,但 super 的使用并不限于方法。在代码中需要调用给定实例的超类方法的任何地方都可以使用它。
  • super 第二个参数是可选的。如果只提供了第一个参数,那么 super 返回的是一个未绑定(unbound)类型。
  • 面对多重继承模式,super 将变得难以使用,与方法解析顺序(Method Resolution Order, MRO)有关。
  • Python 2 中 super() 的工作原理几乎完全相同。调用签名的唯一区别在于简化的零参数形式不可用,因此必须始终提供至少一个参数。Python 2 中的super 只适用于新式类。
  • Python 3 不再保留旧式类的概念,因此,没有继承任何其他类的类都隐式地继承自 object。
  • Python 的方法解析顺序基于 C3,这是为 Dylan 编程语言构建的 MRO。
  • MRO 的变化是用于解决创建公共基本类型(object)所引入的问题。
  • 使用 super 易犯的错误。
    • 混用 super 与显式类调用。
    • 初始化过程中的参数传递。
  • 最佳实践。
    • 应该避免多重继承。
    • super 的使用必须一致:在类的层次结构中,要么全部用 super,要么全不用。
    • 如果代码的使用范围包括 Python 2,在 Python 3 中也应该显式地继承自 object。
    • 调用父类时必须查看类的层次结构。

高级属性访问模式

  • 在一个属性前面加上 __ 前缀,解释器就会立刻将其重命名,Python 提供这一特性是为了避免继承中的名称冲突,因为属性被重命名为以类名为前缀的名称。但在实践中,永远不应使用 __。如果一个属性不是公有的,约定使用 _ 前缀。使用描述符和 property 这些 OOP 设计的关键特性来设计一个清晰的API。
  • 描述符
    • 描述符允许你自定义在引用一个对象的属性时应该完成的事情。
    • 描述符类基于 3 个特殊方法,这3个方法组成了描述符协议:
      • __set__(self, obj, type=None):在设置属性时将调用这一方法。
      • __get__(self, obj, value):在读取属性时将调用这一方法。
      • __delete__(self, obj):对属性调用 del 时将调用这一方法。
    • 实现了 __get__()__set__() 的描述符被称为数据描述符(data descriptor)。如果只实现了 __get__(),那么就被称为非数据描述符(non-data descriptor)。
    • 属性查找顺序:数据描述符优先于 __dict__ 查找,而 __dict__ 查找优先于非数据描述符。
    • 描述符的一个示例用法就是将类属性的初始化延迟到被实例访问时。
  • property
    • property 提供了一个内置的描述符类型,它知道如何将一个属性链接到一组方法上。property 接受 4 个可选参数:fget、fset、fdel 和 doc。最后一个参数可以用来定义一个链接到属性的 docstring,就像是一个方法一样。property 的最佳语法是使用 property 作为装饰器。

元编程

  • 元编程是一种编写计算机程序的技术,这些程序可以将自己看作数据,因此你可以在运行时对它进行内省、生成和/或修改。
  • 装饰器–一种元编程方法。
    • 接受一个函数对象,并在运行时修改它。
  • 类装饰器
    • 与函数装饰器完全相同,唯一的区别在于它的返回值是一个类。
  • 使用 __new__() 方法覆写实例创建过程。
    • 特殊方法 __new__() 是一种负责创建类实例的静态方法。无需使用 staticmethod 装饰器将其声明为静态方法。
    • 只有在 __init__() 不够用的时候,使用 __new__()
  • 元类
    • 元类是定义其他类(型)的一种类(型)。

    • 一般语法:

      • 调用内置的 type() 类可作为 class 语句的动态等效。给定名称、基类和包含属性的映射,它会创建一个新的类对象。
      • 用 class 语句创建的每个类都隐式地使用 type 作为其元类。
      • 虽然可以用显式调用 type() 的函数来替代元类,但通常的做法是使用继承自 type 的另一个类。
    • Python 3 中新的元类语法。

      class ClassWithAMetaclass(metaclass=type):
          pass
      
      • Python 2 的 class 语句不接受关键字参数,所以 Python 3 定义元类的语法会在导入时引发 SyntaxError 异常。
      • Python 2 的元类没有 __prepare__() 钩子(hook)。在 Python 2 中实现这一函数不会引发任何异常,但是没有任何意义,因为它不会被调用以提供干净的命名空间对象。需要依赖更复杂的技巧来完成用 __prepare__() 可以轻松完成的工作。
    • 元类的使用

      • 对于修改读/写属性或添加新属性之类的简单操作,可以避免使用元类,而采用更简单的解决方法,例如 property、描述符或类装饰器。
      • 框架是元类真正适合使用的地方。构造 Django 的 ORM 实现。
    • 使用元类易犯的错误

      • 虽然类的调用签名相当严格,但 Python 并不强制要求返回参数的类型。只要它接受调用的传入参数,并且有必要的属性,那么它可以是任何内容。
  • 一些关于代码生成的提示
    • exec、eval 和 compile 3 个内置函数,用于手动执行、求值和编译任意 Python 代码。
      • exec(object, globals, locals):这一函数允许你动态执行 Python 代码。
      • eval(expression, globals, locals):这一函数用于对给定表达式进行求值并返回其结果。
      • compile(source, filename, mode):这一函数将源代码编译成代码对象或 AST 对象。
    • 抽象语法树
      • Python 语法首先被转换成抽象语法树(Abstract Syntax Tree, AST),然后才被编译成字节码。这是对源代码抽象语法结构的一种树状表示。
    • 使用代码生成模式的项目
      • falcon 的编译路由器:falcon 是一个极简的 Python WSGI Web 框架,用于构建快速又轻量级的 API。
      • Hy:Hy 是完全用 Python 编写的 Lisp 方言。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值