Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
417 views
in Technique[技术] by (71.8m points)

Python: tracking the use of parent class methods

I have taken a very elementary approach to tracking the use of parent class method calls while working with the child instance. I have modified the __getattribute__ method, so that it writes initial parent method calls into child.parent_method_dict, and thereafter calls from the child.parent_method_dict rather than back to the parent class. I am messing with such basic elements here, so I have to ask is there a safer or better way to construct this ability to track parent class method usage. Should I look to somehow assign the parent class methods to the child class so I don't need to use 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

I know I can implement much more complex forms of tracking, or uses of the tracked information. With the about models, I just wanted to see what goes where.

>>> 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>}

The methods return the expected values. The different counts are accurate.

ADDED NOTE to address @Marcin:

Here is a new Parent class:

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

Inside Child.__init__, I added self.sequence = []. Inside def _attr_val(*args, **kwargs), I added self.sequence.append(attr). So now I get:

>>> 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']

Now, I can track the sequence of chained methods. So lets say c.a().b()....n() was a very expensive and also very dependent on the actual sequence. I can now save the value, identified by the sequence needed to calculate it. Additionally, I can easily replicate the sequence at a later time.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...