8.8 向类中添加方法函数

    类装饰器通过两个步骤来创建新方法函数:先创建方法函数,然后将它插入到类中。通常用mixin类比用装饰器更好。一个mixin类的正确用途是用于插入方法。插入方法的另外一种方式更不易于理解,甚至可能会让人觉得惊讶。

    Total_Ordering装饰器的例子中,具体插入什么方法是非常灵活的,它基于类中已经提供了什么。这是典型用法中的一种特殊情况,但是非常明智。

    我们可能想要定义一个标准的memento()方法。我们希望把这个标准的方法包含在多个不同的类中。我们会对比这个设计的装饰和mixin类的版本。下面是用添加一个标准方法的装饰器实现版本。

    def memento( class ):
      def memento( self ):
        return "{0.class.qualname}({0!r})".format(self)
      class
    .memento= memento
      return class_

    这个装饰器包含了一个即将被插入到类中的方法函数。下面演示了如何使用这个@memento装饰器向类中添加方法函数。

    @memento
    class SomeClass:
      def init( self, value ):
        self.value= value
      def repr( self ):
        return "{0.value}".format(self)

    装饰器向类中插入了一个新方法——memento()。但是,这种做法有一些缺点。

    • 我们不能通过重载memento()方法函数的实现来处理特殊情况,它是在定义之后内嵌到类中的。
    • 我们很难扩展装饰器函数。如果我们想要扩展功能或者处理特殊情况,我们必须将它升级为可调用对象。我们准备升级到一个可调用对象,那么我们应该完全放弃这种方法,转而使用一个mixin类添加方法。

    下面是添加一个标准方法的mixin类。

    class Memento:
      def memento( self ):
        return "{0.class.qualname}({0!r})".format(self)

    下面演示了如何使用这个Memento类定义一个类。

    class SomeClass2( Memento ):
      def init( self, value ):
        self.value= value
      def repr( self ):
        return "{0.value}".format(self)

    这个mixin提供了一个新方法——memento(),这是一个mixin类的经典用法。通过扩展Memento mixin类添加功能更容易。另外,我们可以重载memento()方法函数,用于处理特殊情况。