I'd like to provide the capability for users of one of my modules to extend its capabilities by providing an interface to call a user's function. For example, I want to give users the capability to be notified when an instance of a class is created and given the opportunity to modify the instance before it is used.
The way I've implemented it is to declare a module-level factory function that does the instantiation:
# in mymodule.py def factory(cls, *args, **kwargs): return cls(*args, **kwargs)
Then when I need an instance of a class in mymodule, I do factory(cls, arg1, arg2)
rather than cls(arg1, arg2)
.
To extend it, a programmer would write in another module a function like this:
def myFactory(cls, *args, **kwargs): instance = myFactory.chain(cls, *args, **kwargs) # do something with the instance here if desired return instance
Installation of the above callback looks like this:
myFactory.chain, mymodule.factory = mymodule.factory, myFactory
This seems straightforward enough to me, but I was wondering if you, as a Python programmer, would expect a function to register a callback rather than doing it with an assignment, or if there were other methods you would expect. Does my solution seem workable, idiomatic, and clear to you?
I am looking to keep it as simple as possible; I don't think most applications will actually need to chain more than one user callback, for example (though unlimited chaining comes "for free" with the above pattern). I doubt they will need to remove callbacks or specify priorities or order. Modules like python-callbacks or PyDispatcher seem to me like overkill, especially the latter, but if there are compelling benefits to a programmer working with my module, I'm open to them.
A hook is a way to extend software. A callback is a function that is passed as a parameter to another function. A webhook is a hook in the web. Typically used to make two distinct systems communicate and typically to go away from polling towards a publisher-subscriber model.
In Python, a callback is simply a function or a method passed to LocalSolver. A callback takes two parameters: the LocalSolver object that triggers the event and the type of the callback. It is possible to use the same callback method or object for multiple events or multiple LocalSolver instances.
A hook can tell about additional source files or data files to import, or files not to import. A hook file is a Python script, and can use all Python features. It can also import helper methods from PyInstaller.
Taking aaronsterling's idea a bit further:
class C(object): _oncreate = [] def __new__(cls): return reduce(lambda x, y: y(x), cls._oncreate, super(C, cls).__new__(cls)) @classmethod def oncreate(cls, func): cls._oncreate.append(func) c = C() print hasattr(c, 'spew') @C.oncreate def spew(obj): obj.spew = 42 return obj c = C() print c.spew
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With