'Intercept specific function invocations using parent/child classes?
I am writing a framework that allows us to intercept certain function invocations so that we can manage them(enforce timeouts and retries, persist return values etc.). Right now I'm thinking of introducing an abstract class with a method that invokes an abstract method and forcing users/clients to inherit the abstract class and do their function invocations inside the abstract method.
Specifically, I am writing an abstract class Fruit that expects clients to:
- Extend
Fruitand override theeat_fruitmethod - Invoke the
eatmethod when actually wanting to use the overrideneat_fruitmethod
The reason I'm thinking of doing this is that we want to record the number of eat_fruit invocations
class Fruit:
def eat(self, *args, **kwargs):
self.eat_fruit(*args, **kwargs)
def eat_fruit(self, *args, **kwargs):
pass
class Apple(Fruit):
def eat_fruit(self, *args, **kwargs):
print("Eat Apple")
apple = Apple()
apple.eat()
However, we're running into a problem with extensibility. Let's say the client needs to add input parameter color to Apple's eat_fruit method, they can add it like this:
class Fruit:
def eat(self, *args, **kwargs):
self.eat_fruit(*args, **kwargs)
def eat_fruit(self, *args, **kwargs):
pass
class Apple(Fruit):
def eat_fruit(self, color, *args, **kwargs):
print("Eat "+ color + " Apple")
apple = Apple()
apple.eat("Red")
This is workable but relies on them knowing that Fruit's eat method passes *args and **kwargs directly to the eat_fruit method, which seems to be an implementation detail in the eat method that may be subject to change.
I'm wondering if there are better ways to accomplish the same thing. In particular,
- Is it possible for them to invoke
eat_fruitdirectly(rather than invoking the parent class'seatmethod and assume that the arguments will be forwarded toeat_fruit)? I can't think of a way for them to do that while still letting us keep track ofeat_fruitinvocations - Is there a better way(rather than using parent-child classes) to intercept function invocations? The final goal of this framework is to intercept specific function invocations made by clients so that we can manage them(enforce timeouts and retries, persist return values etc.).
Thanks! Jessica
Solution 1:[1]
In my experience, frameworks and APIs solve this via an Event-driven architecture.
While other methods might solve your problems, like with decorators, if you want full control over what is happening, you can consider this architecture.
Basically, instead of executing functions directly, you "fire" or "invoke" an "event" that is associated with that function, but which also can be associated with multiple functions. The user can have their own functions, and the framework can have its own functions, without either party having to know too much about the other. The user is happy that his functions are executing, and the framework is happy to have control over any event that is fired or invoked.
However this is not a small feature that a framework can have, especially if you are implementing it from scratch. So when considering to provide this feature in your framework, it is worth checking if the language you are using already has support for it or if a 3rd party library is available that can provide this feature for you.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
