Python:跟踪父类方法的使用

时间:2013-10-31 19:39:22

标签: python

在使用子实例时,我采用了一种非常基本的方法来跟踪父类方法调用的使用。我修改了__getattribute__方法,以便将初始父方法调用写入child.parent_method_dict,然后从child.parent_method_dict调用而不是返回父类。我在这里弄乱这些基本元素,所以我不得不问有没有更安全或更好的方法来构建跟踪父类方法用法的能力。我应该以某种方式将父类方法分配给子类,这样我就不需要使用parent_method_dict了吗?

class Parent(object):
    def __init__(self):
        pass

    def a(self, *args, **kwargs):
        return 'hello'

    def b(self, *args, **kwargs):
        return 'goodbye'

class Child(Parent):
    def __init__(self):
        super(Child, self).__init__()
        self.count = 0
        self.parent_method_dict = {}

    def __getattribute__(self, attr):
        if attr not in ['a', 'b']:
            return super(Child, self).__getattribute__(attr)

        _parent_dict = self.parent_method_dict
        if attr in _parent_dict:
            _attr =  _parent_dict[attr]
            _attr.func_count += 1
            return _attr

        _attr = super(Child, self).__getattribute__(attr)
        print 'getting attribute {}'.format(attr)

        if callable(_attr):
            print 'can return value'

            def _attr_val(*args, **kwargs):
                print 'calculating value'
                print 'self', self
                self.count += 1
                return_val = _attr(*args, **kwargs)
                return return_val

            _attr_val.func_count = 0
            _parent_dict[attr] = _attr_val
            return _attr_val

        _parent_dict[attr] = _attr
        return _attr

我知道我可以实施更复杂的跟踪形式,或使用跟踪信息。关于模型,我只想看看会发生什么。

>>> child = Child()
>>> child.count
0
>>> child.a()
getting attribute a
can return value
calculating value
self <Child object at 0x1036575d0>
'hello'
>>> child.a()
calculating value
self <Child object at 0x1036575d0>
'hello'
>>> child.b()
getting attribute b
can return value
calculating value
self <Child object at 0x1036575d0>
'goodbye'
>>> child.count
3
>>> child.a.func_count
2
>>> child.b.func_count
1
>>> child.parent_method_dict
{'a': <function _attr_val at 0x1035d5f50>, 'b': <function _attr_val at 0x1035d5848>}

方法返回预期值。不同的计数是准确的。

添加注释以解决@Marcin:

这是一个新的Parent类:

class Parent(object):
    def __init__(self):
        pass
    def a(self, *args, **kwargs):
        print 'hello'
        return self
    def b(self, *args, **kwargs):
        print 'goodbye'
        return self

Child.__init__内,我添加了self.sequence = []。在def _attr_val(*args, **kwargs)内,我添加了self.sequence.append(attr)。所以现在我得到了:

>>> c = Child()
>>> c.a().b().a().a().b()
getting attribute a
can return value
calculating value
self <Child object at 0x10361fe90>
hello
getting attribute b
can return value
calculating value
self <Child object at 0x10361fe90>
goodbye
calculating value
self <Child object at 0x10361fe90>
hello
calculating value
self <Child object at 0x10361fe90>
hello
calculating value
self <Child object at 0x10361fe90>
goodbye
<Child object at 0x10361fe90>
>>> c.sequence
['a', 'b', 'a', 'a', 'b']

现在,我可以跟踪链式方法的顺序。所以我们说c.a().b()....n()是非常昂贵的,也非常依赖于实际的序列。我现在可以保存由计算它所需的序列标识的值。另外,我可以在以后轻松复制序列。

0 个答案:

没有答案