【问题标题】:How do I intercept operations via subclassing?如何通过子类化拦截操作?
【发布时间】:2011-10-31 14:12:01
【问题描述】:

我正在学习 Python 第 4 版,目前正在编写本书第六部分的练习。我目前正在进行的练习有点让我困惑,我希望我能得到一些关于如何解决它的指导。

这是我正在处理的提示。

子类化。从练习 2 中创建一个名为 MyListSub 的 MyList 子类,它扩展 MyList 以在调用每个重载操作之前将消息打印到标准输出并计算调用次数。 MyListSub 应该从 MyList 继承基本方法行为。将序列添加到 MyListSub 应该打印一条消息,增加 + 调用的计数器,并执行超类的方法。此外,引入一种将操作计数器打印到标准输出的新方法,并以交互方式对您的类进行试验。您的计数器是否计算每个实例或每个类(对于该类的所有实例)的调用?您将如何对另一个选项进行编程)? (提示:这取决于计数成员分配给哪个对象:类成员由实例共享,但自身成员是每个实例的数据。)

所以我现在真正感兴趣的部分是

从练习 2 中创建一个名为 MyListSub 的 MyList 子类,它扩展 MyList 以在调用每个重载操作之前将消息打印到标准输出并计算调用次数。

我可以在这里看到 DRY 的一个很好的用途,它可以用一块石头杀死我所有的鸟。但我只是不知道如何实现它。 我知道我应该做的是实现某种方法来拦截操作、递增计数器并打印消息。但我不知道如何最好地做到这一点。我的基本想法是

def count_ops(self, op_count):
    # intercept calls to operator overloading methods
    op_count += 1
    print 'Number of calls to operator {0}: {1}'.format(oper, op_count)

(注意:这不是我写的代码,这是用于突出我想要做的边界伪代码。)

我能在这里得到一点帮助吗?请不要直接给我答案,我想弄清楚这一点,提示比答案更进一步。 :)

【问题讨论】:

    标签: python oop class dry


    【解决方案1】:

    提示:

    def count(cls):
        for attr in (attr for attr in dir(cls) if not attr.startswith('_')):
            method = getattr(cls,attr)
            if callable(method):
                setattr(cls,attr,func_count(method,attr))
        return cls
    

    【讨论】:

    • 我已经有了这样的解决方案,我希望进一步解耦它,这样我就不必在每个重载的方法中添加一些东西。
    • 你可以使用类装饰器来做到这一点。
    【解决方案2】:

    除了计算调用之外,您的重载方法是否还在做其他事情?换句话说,你必须写它们吗?如果是的话,你可以使用装饰器,或者只是一个单独的函数,就像一个单独的函数,并从每个方法中调用它。

    如果子类中唯一需要的重载是计数,您可以查看__getattribute__。请注意——它有点复杂,在您将它用于生产代码之前,您需要彻底了解它。其他选项包括 class decoratormetaclass 来包装您关心的每个方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-03-31
      • 2015-04-16
      • 1970-01-01
      • 2011-07-15
      • 1970-01-01
      • 1970-01-01
      • 2019-03-27
      • 2020-01-19
      相关资源
      最近更新 更多