如何通过子类拦截操作?

时间:2011-10-31 14:12:01

标签: python oop class dry

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

这是我正在使用的提示。

  

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

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

  

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

我可以在这里看到很好地使用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)

(注意:这不是我编写的代码,这是边缘伪代码,以突出我想要做的事。)

我可以在这里得到一些帮助吗?请不要直截了当地给我答案我想弄明白这一点,并且提示远远超过答案。 :)

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

除了计算通话之外,您的重载方法是否正在执行其他操作?换句话说,你还要写它们吗?如果是,你可以使用装饰器,或者只是一个单独的函数,并从每个方法中调用它。

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