Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I intercept operations via subclassing?

I'm working through Learning Python 4th Edition and I'm currently working on the exercises for part VI of the book. The exercise I'm currently on is kind of confusing me and I was hoping I could get a little guidance as to how I can solve it.

Here's the prompt I'm working with.

Subclassing. Make a subclass of MyList from exercise 2 called MyListSub, which extends MyList to print a message to stdout before each overloaded operation is called and counts the number of calls. MyListSub should inherit basic method behavior from MyList. Adding a sequence to a MyListSub should print a message, increment the counter for + calls, and perform the superclass’s method. Also, introduce a new method that prints the operation counters to stdout, and experiment with your class interactively. Do your counters count calls per instance, or per class (for all instances of the class)? How would you program the other option)? (Hint: it depends on which object the count members are assigned to: class members are shared by instances, but self members are per-instance data.)

So the part I'm really interested in right now is the

Make a subclass of MyList from exercise 2 called MyListSub, which extends MyList to print a message to stdout before each overloaded operation is called and counts the number of calls.

I can see a good use of DRY right here that'll kill all my birds with one stone. But I just don't know how to implement it. I know that what I should do is implement some kind of method that intercepts operations, increments a counter and prints a message. But I don't know how to best go about that. My basic idea is something like

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)

(Note: This isn't code I've written yet, this is borderline pseudocode to highlight what I want to do.)

Can I get a little help here? Please don't give me the answer outright I want to figure this out and hints go much further than answers. :)

like image 370
wldcordeiro Avatar asked Mar 22 '26 11:03

wldcordeiro


2 Answers

Hint:

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
like image 141
unutbu Avatar answered Mar 24 '26 01:03

unutbu


Are your overloaded methods doing anything else besides counting the calls? In other words, do you have to write them anyway? If yes, you could use decorators, or just a seperate function like the one have and call it from each method.

If the only overloading needed in the subclass is the counting you can look into __getattribute__. Be warned -- it's a bit complicated, and you will want a thorough understanding of it before you ever used it in production code. Other options include a class decorator or a metaclass to wrap each of the methods you care about.

like image 25
Ethan Furman Avatar answered Mar 24 '26 00:03

Ethan Furman



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!